Подтвердить что ты не робот

Почему параметр шаблона шаблона не позволяет "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 не разрешено в объявлениях шаблонов шаблонов?
  • Стандарт С++ говорит об этом?
4b9b3361

Ответ 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.