首页 文章

为什么模板模板参数不允许参数列表后面的'typename'

提问于
浏览
28

模板模板typename?

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

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

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

您可以争辩说使用模板模板时的要求是提示您应该传递 class type ,但情况并非总是如此(特别是在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 回答

  • 31

    Short answer :因为Standard says so .

    Longer answer :在标准化之前,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, Headers 为 Allow typename in a template template parameter ,并建议准确允许 .

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

  • 7

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

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

    如今,这样的参数可以是类模板的名称或 alias templates ,由于这些参数甚至没有远程连接,因此关键字 class 的强制执行或多或少已经过时 . 建议N4051选择用C 1Z改变这个 .

相关问题