C++ 为什么下面的模板声明格式不正确?

C++ 为什么下面的模板声明格式不正确?,c++,templates,c++11,standards,C++,Templates,C++11,Standards,为什么以下声明无效 template<template<typename> typename T> struct S {}; 模板 结构S{}; 我认为这是有效的,因为以下内容是有效的: template<template<typename> class T> struct S {}; 模板 结构S{}; 从[gram.temp]中的标准中可以看出,它似乎是有效的,但gcc给出了以下输出: prog.cpp:4:38: error: exp

为什么以下声明无效

template<template<typename> typename T>
struct S {};
模板
结构S{};
我认为这是有效的,因为以下内容是有效的:

template<template<typename> class T>
struct S {};
模板
结构S{};
从[gram.temp]中的标准中可以看出,它似乎是有效的,但gcc给出了以下输出:

prog.cpp:4:38: error: expected 'class' before 'T'
 template<template<typename> typename T>
                                  ^
prog.cpp:4:38:错误:在“T”之前应为“class”
模板
^
基本上,“因为标准这么说。”C++11 14.1/1列出了类型参数的语法:

类型参数:
class
..
opt-identifieropt
class
identifieropt
=
type id
typename
..
opt identifieropt
typename
identifieropt
=
type id
模板
..
选择标识符opt
模板
标识符opt
=
id表达式

如您所见,模板参数只允许使用
class

我的猜测是,任何类型都可以用作类型参数,包括非类类型。但在C++11之前,没有“非类类型模板”这类东西,唯一的类型模板是类模板


C++11的别名模板改变了这一点,但模板参数语法显然没有跟上。然而,在后C++11(实际上是后C++14)中,这一限制实际上被取消了,
template typename
是有效的模板参数语法。

在N4296中,它的指定方式有所不同。在14.1/1中,它似乎有所不同。这是否意味着这个限制将要改变?@MathiasVorreiterPedersen显然是这样。“唯一的类型模板是类模板。”别名templates@Columbo刚才提到了它,虽然从技术上讲,它是一个“后C++11”草案,但n4296也是后C++14。这是C++1z的最新版本