typename,类型成员和非类型成员:它是有效的代码吗?
考虑下面的代码:typename,类型成员和非类型成员:它是有效的代码吗?
struct S {
struct type {};
type type;
};
int main() {
typename S::type t;
(void) t;
}
除了一个事实,即是远不是一个好主意,我看了这里SO另一个问题后进行试验。
我发现上面的代码片段是compiled with no errors by GCC,它是rejected by clang 3.9,出现以下错误:
error: typename specifier refers to non-type member 'type' in 'S'
我怀疑铛就在这种情况下,和GCC是错误的(实际上,我打开一个问题的后者)。
这是正确的结论还是typename
的有效使用?
注:我不是问如何解决它,我知道如何做到这一点。我只问这个代码是否有效。
The usual qualified name lookup is used to find the qualified-id even in the presence of
typename
.
也就是说,不像的情况下阐述类型说明符秒,在这种情况下,不忽略非类型名称的名称查找。
If the qualified-id in a typename-specifier does not denote a type or a class template, the program is ill-formed.
所以有问题的程序是病态的。
[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'是类型名称和非类型名称,非类型名称隐藏类型名称。 – cpplearner
虽然这是模板名称解析,但在OP的问题中没有涉及,我不认为可以说规则是相同的。 –
较旧的gcc像4.4.7拒绝它太:http://melpon.org/wandbox/permlink/Oh2Rp4jWjGPIoIwv – marcinj
Couldn”在标准中找到关于这种合法性的任何东西。尽管如此,'typename'只是在模板方面提到的,所以也许这是一种违背精神的行为?无论如何,解决这种特定歧义的正确和标准方法似乎是'struct S :: type t;' – StoryTeller
@marcinj这似乎是因为GCC 4.4.7没有在外部实现[CWG 382:允许'typename' (http://wg21.link/cwg382)。 – cpplearner