【问题标题】:Why does not a template template parameter allow 'typename' after the parameter list为什么模板模板参数不允许在参数列表之后使用'typename'
【发布时间】:2014-07-27 16:46:13
【问题描述】:

模板模板类型名称?

当使用template <template <typename> class T>中的模板模板语法时,需要使用关键字class,因为使用typename会产生如下错误:

错误:模板模板参数在参数列表后需要'class'

在其他任何地方,关键字typenameclass 在声明模板参数的基本情况下是可以互换的。

您可能会争辩说,使用模板模板时的要求是暗示您应该传递一个类类型,但情况并非总是如此(尤其是在 C++11 引入模板化之后类型别名)。

template <template <typename> class T> // 'class' keyword required.
struct Foo {
    using type = T<int>;
};

template <typename T>
using type = T (*)();

using func_ptr_t = Foo<type>::type;

这背后的原因是什么?

  • 是否有任何具体原因说明为什么模板模板声明中不允许typename
  • C++ 标准对此有什么规定吗?

【问题讨论】:

标签: c++ templates c++11 language-lawyer typename


【解决方案1】:

简答:因为Standard says so

更长的答案:在标准化之前,C++ 模板要求所有模板参数都使用 class 关键字。然而,为了强调模板也可以是非类(即内置)类型的事实,引入了替代关键字typename。但是,在 C++98 中,模板模板参数只能是类类型,这就是没有在该上下文中添加 typename 关键字的原因。

进入 C++11 及其新功能 template aliases,现在还引入了非类模板,因此也引入了非类模板模板参数:

template<typename T> struct A {};
template<typename T> using B = int;

template<template<typename> class X> struct C;
C<A> ca; // ok
C<B> cb; // ok, not a class template
template<template<typename> typename X> struct D; // error, cannot use typename here

上述示例取自当前 C++1z 提案 N4051,标题为Allow typename in a template template parameter,并建议准确地允许这样做。

Clang 3.5 SVN now supports this 带有 -std=c++1z 标志。

【讨论】:

  • Visual Studio 2015 现在也支持 N4051(刚刚检查)。
【解决方案2】:

我正在寻找这个限制背后的原因 [...]

在引入 C++11 之前,您可以传递给模板模板参数的唯一模板是 class 模板。 这就是强制使用关键字class 的原因。 此外,关键字typename 暗示模板参数是对任意type 而非template 的替代,因此在该上下文中使用typename 只会模糊类型的名称和(class模板之间的行。 这是可以理解的。

如今,此类参数可以是类模板的名称或别名模板,由于它们甚至没有远程连接,因此关键字class 的实施或多或少已经过时。提案N4051 选择用 C++1Z 来改变它。

【讨论】:

  • 在提出问题(2014 年 6 月 6 日)之前给出了这个答案(2014 年 5 月 31 日)。这怎么可能???
  • @Walter 从stackoverflow.com/questions/23965105/…合并而来。
  • @T.C.唔。为什么合并将第一个问题标记为重复(因此禁止对其进行投票)而不是第二个问题?请注意,有一个偶数older question 相同的内容。不也应该合并吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
  • 2017-07-05
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
相关资源
最近更新 更多