是否符合C++标准,使用`A <int> :: template B <int> x;`来定义变量?

xml*_*lmx 6 c++ compiler-construction portability templates c++11

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?
};
Run Code Online (Sandbox Code Playgroud)

是否符合C++标准,使用A<int>::template B<int> x;?定义变量?

dyp*_*dyp 12

虽然这是一个非规范性的说明,但我认为答案可以由n3797 [temp.names]/6给出.

typename前缀的情况一样,在template不是绝对必要的情况下允许使用前缀; 即,当嵌套名称说明符或在左侧的表达->.上的模板参数不依赖,或者利用没有出现在模板的范围.

在OP的示例中,前缀template在模板范围之外使用,前面的嵌套名称说明符不依赖.因此,前缀template不是必需的,但在此允许.


[expr.prim.general]/8

qualified-id:
     nested-name-specifier templateopt   unqualified-id

另外[temp.names]/5

以关键字为前缀的名称template应为template-id,或者名称应引用类模板.

[temp.names]/1表示这B<int>确实是一个(简单的)模板ID.

  • @Constructor在C++ 03中,即使*nested-type-name*不依赖,也可以使用关键字`template`; 但是你不允许在模板范围之外使用它. (2认同)