Joh*_*eek 11
它符合C++ 03/C++ 11编译器的有效性,适用于"有效"的定义.
C++ 03 ISO/IEC 14882:2003§14.2.5:
[ 注意:就像
typename前缀的情况一样,在template不是绝对必要的情况下允许使用前缀; 即,当->or.或左侧的表达式或嵌套名称说明符不依赖于模板参数时.]
C++ 11 ISO/IEC 14882:2011§14.2.5:
[ 注意:与
typename前缀的情况一样,在template不是绝对必要的情况下允许使用前缀; 即,当嵌套名称说明符或在左侧的表达->或.上的不依赖模板的参数,或使用未出现在模板的范围.- 结束说明 ]
请注意,template当相关成员实际上不是模板时,您无法使用- 您不允许使用它.另请注意,对于typename,类型必须是限定类型(例如X::Y,不仅仅是X).C++ 11也改变了它,因此你不必在模板的范围内,而C++ 03要求你在模板中.另请注意,编译器在实际上是否允许您这样做时可能会有所不同.例如,在Clang的旗帜下,这会发出警告-Wc++11-extensions.
以下是一些示例,假设以下定义:
struct X {
typedef int Y;
template <typename T> static void foo();
static void bar();
template <typename T> static void baz(T);
};
Run Code Online (Sandbox Code Playgroud)
在C++ 03和C++ 11中都无效:
template <typename T>
void foo() {
typename int z = 0; // int is not a qualified name.
X::template bar(); // X::bar is not a template.
X::template baz(z); // no template argument list.
}
Run Code Online (Sandbox Code Playgroud)
在C++ 03中无效,在C++ 11中有效(但在我的Clang副本上产生警告):
void bar() {
typename X::Y z = 0; // not in the body of a template, so
X::template foo<int>(); // no possibility of dependent names.
}
Run Code Online (Sandbox Code Playgroud)
在C++ 03和C++ 11中都有效:
template <typename T>
void baz() {
typename X::Y z = 0; // not a dependent name, so 'typename'
X::template foo<int>(); // isn't strictly necessary.
}
Run Code Online (Sandbox Code Playgroud)