gcc和class关键字

rip*_*rip 8 c++ gcc templates

我知道,typenameclass关键字是模板参数互换,但我认为只typename被允许嵌套类规范.

一旦我意外地为嵌套类错误地写了" class"而不是" typename".我发现gcc也接受class了,所以你可以这样写:

class std::vector<T>::iterator it;
instead of
typename std::vector<T>::iterator it;
Run Code Online (Sandbox Code Playgroud)

在你的模板中.

这是一个gcc错误还是标准真的允许这种语法?

更新:代码示例:

template <typename T>
void test()
{
     class std::vector<T>::iterator it;
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*itb 2

class a::b是一个详细的类型说明符。详细类型说明符的名称查找会忽略非类型名称。因此,如果您正在解析模板,您可以假设两件事:

  • 当我们实例化并对 进行名称查找时b,名称查找要么为我们提供类型,要么出错(找不到任何名称)。

由于这个原因,在 C++0x 中class a::b不需要typename(无论如何你不能将它放在详细的类型说明符上的任何地方)。C++03 不允许这样做,因此 GCC 似乎将 C++0x 规则作为扩展来实现。

这并不是特别糟糕。每个真正的编译器都会代表他们在其 C++03 版本中实现合理且易于实现的规则,即使他们需要正式拒绝它。但是,class a::b 必须查找类名。如果它只是一个 typedef,那么对详细类型说明符的查找是无效的。

请注意,这class a::b是在查找中忽略非类型名称的唯一方法(除了::具有类似特殊规则的限定名称中的 a 之前的神秘情况)。例如

template<typename T> 
struct A { typename T::type t; } 

struct B { class type { }; int type; };

// invalid, even though GCC accepts that incorrectly
A<B> a;
Run Code Online (Sandbox Code Playgroud)

如果编译为 C++0x 并使用class T::type t;,则代码变得有效,因为class T::type忽略数据成员,但找到嵌套类。