Почему параметр шаблона шаблона не позволяет "typename" после списка параметров
Шаблонное имя шаблона?
При использовании синтаксиса шаблона шаблона, как в template <template <typename> class T>
, необходимо использовать ключевое слово class
, так как использование typename
дает ошибку в строках:
ошибка: для параметра шаблона шаблона требуется "класс" после списка параметров
В остальных случаях ключевые слова typename
и class
взаимозаменяемы в основном случае объявления параметра шаблона.
Можно утверждать, что требование при использовании шаблона шаблона - это намек на то, что вы ожидаете передать тип класса , но это не всегда так (особенно после того, как С++ 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
не разрешено в объявлениях шаблонов шаблонов?
- Стандарт С++ говорит об этом?
Ответы
Ответ 1
Короткий ответ: потому что Стандарт говорит.
Более длинный ответ: до стандартизации для шаблонов С++ требуется ключевое слово class
для всех параметров шаблона. Однако, чтобы подчеркнуть тот факт, что шаблоны также могут быть неклассического типа (т.е. Встроенного), было введено альтернативное ключевое слово typename
. Однако в С++ 98 параметры шаблона шаблона могут быть только типа класса, и именно по этой причине ключевое слово typename
не было добавлено в этом контексте.
Введите С++ 11 и его новую функцию псевдонимы шаблонов, которые теперь также внедрили неклассические шаблоны, и, следовательно, параметры шаблона-шаблона без класса:
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
Приведенный выше пример был взят из текущего предложения С++ 1z N4051 под названием Разрешить typename
в параметре шаблона шаблона, и предлагает точно указать это.
Clang 3.5 SVN теперь поддерживает этот с флагом -std=c++1z
.
Ответ 2
Я ищу рациональное позади это ограничение [...]
До появления С++ 11 единственными шаблонами, которые вы могли передать параметру шаблона шаблона, были шаблоны class.
Именно поэтому было применено использование ключевого слова class
.
Кроме того, ключевое слово typename
подразумевает, что параметр шаблона является заменой для произвольного типа, а не шаблона, поэтому использование typename
в этом контексте просто размывает линию между именами типов и (класса) шаблонов.
Это понятно.
В настоящее время такими аргументами могут быть имена шаблонов классов или шаблоны псевдонимов, и поскольку они даже не связаны удаленно, принудительное использование ключевого слова class
более или менее устарело. Предложение N4051 позволяет изменить это с помощью С++ 1Z.