Разница ключевых слов "typename" и "class" в шаблонах? - PullRequest
415 голосов
/ 08 января 2010

Для шаблонов я видел оба объявления:

template < typename T >
template < class T >

Какая разница?

А что именно означают эти ключевые слова в следующем примере (взятом из статьи о шаблонах в немецкой Википедии)?

template < template < typename, typename > class Container, typename Type >
class Example
{
     Container< Type, std::allocator < Type > > baz;
};

Ответы [ 5 ]

361 голосов
/ 08 января 2010

typename и class взаимозаменяемы в базовом случае указания шаблона:

template<class T>
class Foo
{
};

и

template<typename T>
class Foo
{
};

эквивалентны.

Сказав это, есть конкретные случаи, когда есть разница между typename и class.

Первый относится к зависимым типам. typename используется для объявления, когда вы ссылаетесь на вложенный тип, который зависит от другого параметра шаблона, такого как typedef в этом примере:

template<typename param_t>
class Foo
{
    typedef typename param_t::baz sub_t;
};

Второй вопрос, который вы на самом деле показываете в своем вопросе, хотя, возможно, не понимаете этого:

template < template < typename, typename > class Container, typename Type >

При указании шаблона ключевое слово class ДОЛЖНО использоваться, как указано выше - оно не , которое может быть заменено typename, в данном случае (примечание начиная с C ++ 17 в этом случае разрешены оба ключевых слова) .

Вы также должны использовать class при явном создании шаблона:

template class Foo<int>;

Я уверен, что есть другие случаи, которые я пропустил, но суть в следующем: эти два ключевых слова не эквивалентны, и это некоторые распространенные случаи, когда вам нужно использовать одно или другое.

77 голосов
/ 08 января 2010

Для именования параметров шаблона typename и class эквивалентны. §14.1.2:

Нет семантической разницы между классом и typename в Шаблон-параметр.

typename однако возможно в другом контексте при использовании шаблонов - намекнуть компилятору, что вы ссылаетесь на зависимый тип. §14.6.2:

Имя, используемое в объявлении шаблона или определение, и это зависит от Предполагается, что параметр шаблона не Назовите тип, если не применимо имя поиск находит имя типа или имя определяется ключевым словом typename.

Пример:

typename some_template<T>::some_type

Без typename компилятор не может вообще сказать, имеете ли вы в виду тип или нет.

18 голосов
/ 08 января 2010

Хотя технических различий нет, я видел, как они используются для обозначения немного разных вещей.

Для шаблона, который должен принимать любой тип как T, включая встроенные модули (например, массив)

template<typename T>
class Foo { ... }

Для шаблона, который будет работать только в том случае, когда T - реальный класс.

template<class T>
class Foo { ... }

Но имейте в виду, что это просто стиль, который используют некоторые люди. Не предписано стандартом или не применяется компиляторами

6 голосов
/ 08 января 2010
  1. без разницы
  2. Параметр типа шаблона Container сам по себе является шаблоном с двумя параметрами типа.
4 голосов
/ 08 декабря 2012

Этот фрагмент фрагмента взят из учебника с ++. Хотя я уверен, что это неправильно.

Каждому параметру типа должно предшествовать ключевое слово class или typename:

// error: must precede U with either typename or class
template <typename T, U> T calc(const T&, const U&);

Эти ключевые слова имеют одинаковое значение и могут использоваться взаимозаменяемо в списке параметров шаблона. Список параметров шаблона может использовать оба ключевых слова:

// ok: no distinction between typename and class in a template parameter list
template <typename T, class U> calc (const T&, const U&);

Может показаться более интуитивно понятным использовать ключевое слово typename, а не class для обозначения параметра типа шаблона. В конце концов, мы можем использовать встроенные (не классовые) типы в качестве аргумента типа шаблона. Более того, typename более четко указывает на то, что следующее имя является именем типа. Однако typename было добавлено в C ++ после того, как шаблоны уже широко используются; некоторые программисты продолжают использовать класс исключительно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...