以下代码被 gcc、vc++ 和 clang 接受。
template<class T>
struct A
{
template<class U>
struct B
{};
};
int main()
{
A<int>::B<int> y; // OK as expected
A<int>::template B<int> x; // Also OK! Is this standard-compliant?
};
使用
A<int>::template B<int> x;
定义变量符合 C++ 标准吗?
虽然这是一个非规范性的注释,但我认为n3797[temp.names]/6可以给出答案
与
前缀一样,在非绝对必要的情况下允许使用typename
前缀;即,当 nested-name-specifier 或template
或->
左侧的表达式不依赖于模板参数,或者使用未出现在模板范围内时。.
在OP的示例中,前缀
template
在模板范围之外使用,并且前面的nested-name-specifier不相关。因此,前缀 template
不是必需的,但在这里是允许的。
[expr.prim.general]/8
合格 ID :
嵌套名称说明符opt 不合格-idtemplate
加上[临时名称]/5
以关键字
为前缀的名称应为 template-id 或名称应引用类模板。template
[temp.names]/1 表示
B<int>
确实是 (simple-)template-id。