Разница ключевых слов 'typename' и 'class' в шаблонах?



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



template < typename T >
template < class T >


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



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



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

5 ответов:

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 при явном создании экземпляра a шаблон:

template class Foo<int>;

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

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

нет никакой семантической разницы между классом и именем типа в a параметр шаблона.

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

имя, используемое в объявлении шаблона или определение, и это зависит от один template-параметр предполагается не использовать назовите тип, если соответствующее имя поиск находит имя типа или имя квалифицируется ключевым словом typename.

пример:

typename some_template<T>::some_type

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

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

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

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

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

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

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

  1. никакой разницы
  2. шаблона параметр типа Container сам шаблон с двумя параметрами типа.

этот фрагмент фрагмента из C++ primer book. Хотя я уверен, что это неправильно.

каждому параметру типа должно предшествовать ключевое слово 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++ после того, как шаблоны уже широко использовались; некоторые программисты продолжают использовать класс исключительно

Comments

    Ничего не найдено.