Why does not a template template parameter allow 'typename' after the parameter list

强颜欢笑 提交于 2019-12-30 09:45:08

问题


Template template typename?

When using template template syntax as in template <template <typename> class T>, it is required to use the keyword class, as using typename gives an error along the lines of:

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

Everywhere else the keywords typename and class are interchangeable in the basic case of declaring a template parameter.

You could argue that the requirement when using template template is a hint that you are expected to pass a class type, but this is not always the case (especially not after C++11 introduced templated type aliases).

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;

What is the reasoning behind this?

  • Is there any specific reason as to why typename is not allowed in template template declarations?
  • Does the C++ standard say anything about this?

回答1:


Short answer: because the Standard says so.

Longer answer: prior to Standardization, C++ templates required the class keyword for all template parameters. However, to stress the fact that templates could also be of non-class (i.e. builtin) type, an alternative keyword typename was introduced. However, in C++98, template-template parameters could only be of class-type, and this was the reason that the typename keyword was not added in that context.

Enter C++11 and its new feature template aliases, that now also introduced non-class templates, and hence non-class template-template parameters:

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

The above example was taken from the current C++1z proposal N4051 titled Allow typename in a template template parameter, and proposes to allow precisely that.

Clang 3.5 SVN now supports this with the -std=c++1z flag.




回答2:


I'm looking for the rational behind this restriction [...]

Before C++11 was introduced, the only templates you could pass to a template template parameter were class templates. That's why the use of the keyword class was enforced. Additionally, the keyword typename implies that the template parameter is a substitution for an arbitrary type and not a template, so using typename in that context would just blur the line between the names of types and (class) templates. That's comprehensible.

Nowadays, such arguments can be the names of class templates or alias templates, and since those aren't even remotely connected, the enforcement of the keyword class is more or less obsolete. The proposal N4051 opts to change this with C++1Z.



来源:https://stackoverflow.com/questions/23965105/why-cant-template-template-parameters-be-introduced-with-typename

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!