Разница ключевых слов "typename" и "class" в шаблонах?
для шаблонов я видел оба заявления:
template < typename T >
template < class T >
в чем разница?
и что именно означают эти ключевые слова в следующем примере (взято из немецкой статьи Википедии о шаблонах)?
template < template < typename, typename > class Container, typename Type >
class Example
{
Container< Type, std::allocator < Type > > baz;
};
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:
семантической разницы нет между class и typename в 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 { ... }
но имейте в виду, что это чисто имиджевый некоторые люди используют. Не санкционировано стандартом или не применяется компиляторами
этот фрагмент фрагмента из книги c++ primer. Хотя я уверен, что это неправильно.
каждому параметру типа должно предшествовать ключевое слово 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++ после того, как шаблоны уже широко использовались; некоторые программисты продолжают использовать класс исключительно