当试图通过使用带有虚拟参数的模板别名来隐藏基数来混淆它们时,clang 和 gcc 之间的行为差​​异 class

Difference in behaviour between clang and gcc when trying to confuse them by using a template alias with a dummy parameter to conceal the base class

考虑以下 C++ 程序:

class A
{
    protected:
        int x;
};

template<typename X>
using B = A;

template<typename T>
class C : public B<T>
{
    public:
        void f()
        {
            x = 0;
        }
};

int main()
{
}

当使用 -std=c++17 -pedantic-errors 作为编译选项使用 clang 和 gcc 进行编译时,它们的行为不同:Clang 编译没有任何错误,但 gcc 给出了关于无法查找标识符 x 的编译错误。

在这种情况下,c++ 标准是怎么说的?在这种情况下,是否允许这两种行为,或者其中一个编译器是否存在错误?

编译器浏览器link:https://godbolt.org/z/EYvYrr

对于 C++17,GCC 在这里是正确的。

9 A type is dependent if it is

  • a template parameter,

  • [...]

  • a simple-template-id in which either the template name is a template parameter or any of the template arguments is a dependent type or an expression that is type-dependent or value-dependent or is a pack expansion [ Note: This includes an injected-class-name of a class template used without a template-argument-list.  — end note ] , or

B<T>是一个simple-template-id,它的参数是一个依赖类型,因此B<T>表示的类型是依赖的。当使用依赖类型作为基础 class 时,任何继承的成员必须完全由其基础 class 名称限定,或通过 this->.

访问

这看起来与 CWG1390 相似,并且看起来 Clang 的行为与 CWG 关于如何处理此类别名模板的协议一致(在模板定义时急切替换):

1390. Dependency of alias template specializations

According to 17.7.2.1 [temp.dep.type] paragraph 8, a type is dependent (among other things) if it is

  • a simple-template-id in which either the template name is a template parameter or any of the template arguments is a dependent type or an expression that is type-dependent or value-dependent

This applies to alias template specializations, even if the resulting type does not depend on the template argument:

   struct B { typedef int type; };
   template<typename> using foo = B;
   template<typename T> void f() {
     foo<T>::type * x;  //error: typename required
   }

Is a change to the rules for cases like this warranted?

Notes from the October, 2012 meeting:

CWG agreed that no typename should be required in this case. In some ways, an alias template specialization is like the current instantiation and can be known at template definition time.