我知道,typename和class关键字是模板参数互换,但我认为只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)
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忽略数据成员,但找到嵌套类。