为什么模板模板参数不允许' typename'在参数列表之后

时间:2014-06-06 12:03:44

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

模板模板typename?

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 ++标准是否对此有所说明?

2 个答案:

答案 0 :(得分:31)

简短回答:因为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,标题为允许typename在模板模板参数中,并建议准确允许。

带有-std=c++1z标记的

Clang 3.5 SVN now supports this

答案 1 :(得分:7)

  

我正在寻找这种限制背后的理性[...]

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

如今,这些参数可以是类模板或别名模板的名称,由于这些参数甚至没有远程连接,因此关键字class的强制执行或多或少已过时。提案N4051选择使用C ++ 1Z更改此内容。