模板别名的上下文中的模板<> template <>语法是什么?

Yur*_*yro 16 c++ templates

(这个问题与模板模板参数无关.)

我刚刚发现GCC编译了这样的代码

template <typename A, typename B>
struct P {};

template <typename A>
template <typename B>
using Q = P<A, B>;
Run Code Online (Sandbox Code Playgroud)

哪个Q是双重模板的名字.

但我不能用这个.当我写作时Q<short><long>,我明白了

template_template.cpp:10:5: error: ‘Q<short int>’ is not a template
     Q<short><long>{};
     ^~~~~~~~
template_template.cpp:10:20: error: invalid use of incomplete type ‘Q<short int>’
     Q<short><long>{};
                    ^
template_template.cpp:2:8: note: declaration of ‘Q<short int>’
 struct P {};
Run Code Online (Sandbox Code Playgroud)

为什么编译第一个片段?

是否有语法来说服编译器Q<short>实际上是一个模板?

// GCC 6.3.0

int*_*jay 11

C++ 14标准在14p1中说:

声明在一个模板声明
-声明或定义一个函数,类,或者一个变量,或
-定义成员函数,一个构件类,成员枚举,或类模板的或类的静态数据成员嵌套在类模板中,或
- 定义类或类模板的成员模板,或
- 是别名声明

这里声明的内模板的声明是没有以上(这是另一种的模板声明,其本身包含一个别名声明),因此该代码是无效的.

语法的相关部分是:

template-declaration:
    template < template-parameter-list > 声明

alias-declaration:
    using identifier attribute-specifier-seq opt = type-id ;

其中一个声明可以是模板的声明,一个别名声明,或其它类型的声明中.

请注意,语法本身接受给定的代码,但上面文本中的其他限制使其无效.