c++ - 为什么模板模板参数不允许在参数列表后出现 'typename'

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

模板模板类型名称?

当使用 template template 语法时,如 template <template <typename> class T> ,需要使用关键字class ,如使用 typename给出如下错误:

error: template template parameter requires 'class' after the parameter list

其他任何地方的关键字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++ 标准对此有什么规定吗?

最佳答案

简答:因为 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 标志。

关于c++ - 为什么模板模板参数不允许在参数列表后出现 'typename',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24081405/

相关文章:

c++ - 在C++中初始化一个大小不固定的数组

c++ - 将参数包解压到 std::initializer_list 中?

c++ - move 构造函数矫枉过正

C++ 在编译时创建 BSTR/在编译时将长度插入字符串?

C++:头文件中结构的 vector

c++ - 为什么我们会在读取输入后调用 cin.clear() 和 cin.ignore() ?

javascript - 正则表达式匹配 #{} 中的名称以供模板使用

c++ - 模板代码中的默认类型参数错误

c++ - 在 std::for_each 中返回 std::move(f)

c++ - 如何调用模板成员函数?