Разница ключевых слов '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:нет никакой семантической разницы между классом и именем типа в 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 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