【问题标题】:typename, type members and non-type members: is it valid code?类型名称、类型成员和非类型成员:它是有效代码吗?
【发布时间】:2016-11-10 08:59:20
【问题描述】:

考虑以下代码:

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

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

除了这远非一个好主意之外,我在阅读了关于 SO 的另一个问题后正在尝试。
发现上面的sn-p是compiled with no errors by GCC,是rejected by clang 3.9,报错如下:

错误:类型名说明符引用了 'S' 中的非类型成员 'type'

我怀疑在这种情况下 clang 是正确的,而 GCC 是错误的(实际上,我正在向后者提出问题)。
这是正确的结论还是typename 的有效使用?


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

【问题讨论】:

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


【解决方案1】:

[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
}

【讨论】:

  • 但是S::type是一种类型。
  • @GillBates S::type是类型名和非类型名,非类型名隐藏类型名。
  • 虽然这是模板名称解析,OP的问题没有涉及,我认为说规则相同并不安全。
  • @GillBates 所涉及的只是通常的限定名称查找。
  • 这个答案是正确的。我之前讨论过在typename-qualified names 中查找;非类型名称不会被忽略,因此它们会在此处隐藏。 +1
猜你喜欢
  • 1970-01-01
  • 2020-05-31
  • 2016-03-05
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
相关资源
最近更新 更多