为什么以下的模板声明是不正确的?

5
为什么以下声明无效?
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>
                                  ^
1个回答

4
基本上,这是因为“标准规定如此”。C++11 14.1/1列出了type-parameter的语法:

type-parameter:
  class ...opt identifieropt
  class identifieropt = type-id
  typename ...opt identifieropt
  typename identifieropt = type-id
  template < template-parameter-list > class ...opt identifieropt
  template < template-parameter-list > class identifieropt = id-expression

如您所见,只有class可以用于模板模板参数。
我猜测这样做的原因是任何类型都可以用作类型参数,包括非类类型。但在C++11之前,没有“非类类型模板”这样的东西——唯一的类型模板是类模板。
这在C++11的别名模板中已经改变,但是模板模板参数语法显然没有跟上。尽管如此,在C++11(实际上是C++14)之后的草案N4296中,这个限制被取消了,template <class> typename是有效的模板模板参数语法。

在N4296中,它的规定有所不同。在http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf的14.1/1中,它似乎是不同的。这是否意味着这个限制将会改变? - Mathias Vorreiter Pedersen
1
@MathiasVorreiterPedersen 看起来是这样。 - Angew is no longer proud of SO
"唯一的类型模板是类模板。" 别名模板 - Columbo
尽管从技术上讲它是一个“C++11后”的草案,但n4296也是C++14后的。它是C++1z的最新版本。 - Cubbi
提出这个变更的论文是N4051,它是EWG issue 131 - T.C.
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接