注入类名作为类型

时间:2018-07-31 20:26:49

标签: c++ language-lawyer c++17

给出以下代码,

@p_id

主要收益是什么? GCC和MSVC表示1,C叫0。

2 个答案:

答案 0 :(得分:9)

我认为Clang就在这里。 [class.qual]中的规则是:

  

在不忽略函数名称且嵌套名称说明符提名类C的查找中:

     
      
  • 如果在C中查找的 nested-name-specifier 之后指定的名称是{{1 }}([class])或
  •   
  • [...这里无关...]
  •   
     

该名称被认为是为类C的构造函数命名。 [注:例如,构造函数不是精化类型说明符中可接受的查找结果,因此不会使用构造函数代替注入的 -class-name -[注释]] 这样的构造函数名称只能在命名构造函数的声明的 declarator-id 中使用,也可以在using-声明中使用。 [示例:

C
     

-举个例子]

struct A { A(); }; struct B: public A { B(); }; A::A() { } B::B() { } B::A ba; // object of type A A::A a; // error, A​::​A is not a type name struct A::A a2; // object of type A typename C::T一样,它的查找中不忽略函数名称(A::A不会导致函数名称被忽略)。因此,在typename中,当typename C::TC时,名称T被认为是构造函数的名称。由于它不是类型名,因此应该出现替换失败并回退到主模板的情况。

提起86818

答案 1 :(得分:4)

为完成Barry的回答,typename仅对编译器说,以下名称是在模板实例化之前执行的分析的类型。实例化后,将执行名称查找,就好像类型名不存在一样,Django rest framework nested self-referential objects

  

通常的合格名称查找用于查找合格ID ,即使存在typename

所以Clang是正确的。为了获得一致的编译器行为,您可以使用[temp.res]/4 struct C::T代替typename C::T

template <class> using void_t = void;
template <class C, class = void> struct X { enum { v = 0 }; };
template <class C> struct X<C, void_t<struct C::T> > { enum { v = 1 }; };
struct T { };
int main() { return X<T>::v; }
相关问题