为什么以下声明无效?
template<template<typename> typename T>
struct S {};
我认为这是有效的,因为以下是有效的:
template<template<typename> class T>
struct S {};
我可以从[gram.temp]中的标准中读取到的内容似乎是有效的,但gcc给了我以下输出:
prog.cpp:4:38: error: expected 'class' before 'T'
template<template<typename> typename T>
^
基本上,"因为标准是这么说的。"C++11 14.1/1列出了类型参数的语法:
类型参数:
nbsp;class
...
nbsp;class
标识符opt=
类型id
nbsp;typename
...
nbsp;typename
标识符opt=
类型id
nbsp;template
<
模板参数列表>
class
...
opt标识符>opt nbsp;template
<
模板参数列表>
class
标识符opt=
id表达式
正如您所看到的,模板模板参数只允许使用class
。
我对其原理的猜测是,任何类型都可以用作类型参数,包括非类类型。但在C++11之前,没有"非类类型模板"这回事;唯一的类型模板是类模板。
随着C++11的别名模板,这种情况发生了变化,但模板模板参数语法显然没有跟上。然而,在C++11之后(实际上是C++14之后)的草案N4296中,这一限制实际上被取消了,并且template <class> typename
是有效的模板-模板参数语法。