typename,类型成员和非类型成员:它是有效的代码吗?

时间:2016-11-10 08:59:21

标签: c++ gcc clang language-lawyer typename

请考虑以下代码:

struct S {
    struct type {};
    type type;
};

int main() {  
    typename S::type t;
    (void) t;
}

除了这个事实远非一个好主意外,我在SO上阅读了另一个问题后进行了实验。
我发现上面的代码段为compiled with no errors by GCCrejected by clang 3.9numpy,并出现以下错误:

  

错误:typename说明符指的是非类型成员' type'在' S'

我怀疑在这种情况下铿锵是正确的,GCC是错的(实际上,我向后者开了一个问题)。
这是正确的结论还是有效使用typename

注意:我不会问如何解决它,我知道该怎么做。我只询问此代码是否有效。

1 个答案:

答案 0 :(得分:7)

[temp.res]/4

  

即使存在typename,通常使用限定名称查找来查找 qualified-id

也就是说,与 elaborated-type-specifier 的情况不同,在这种情况下,名称查找不会忽略非类型名称。

[temp.res]/3

  

如果 typename-specifier 中的 qualified-id 不表示类型或类模板,则该程序格式错误。

所以这个程序是不正确的。

[temp.res] / 4也有一个例子:

struct A {
  struct X { };
  int X;
};
struct B {
  struct X { };
};
template<class T> void f(T t) {
  typename T::X x;
}
void foo() {
  A a;
  B b;
  f(b);             // OK: T::X refers to B::X
  f(a);             // error: T::X refers to the data member A::X not the struct A::X
}