typename
und class
sind im Grundfall der Angabe einer Vorlage austauschbar:
template<class T>
class Foo
{
};
und
template<typename T>
class Foo
{
};
sind gleichwertig.
Allerdings gibt es spezielle Fälle, in denen es einen Unterschied zwischen typename
und gibt class
.
Der erste ist bei abhängigen Typen. typename
wird verwendet, um zu deklarieren, wenn Sie auf einen verschachtelten Typ verweisen, der von einem anderen Vorlagenparameter abhängt, wie typedef
in diesem Beispiel:
template<typename param_t>
class Foo
{
typedef typename param_t::baz sub_t;
};
Der zweite, den Sie tatsächlich in Ihrer Frage zeigen, obwohl Sie ihn möglicherweise nicht erkennen:
template < template < typename, typename > class Container, typename Type >
Bei der Angabe einer Vorlagenvorlageclass
MUSS das Schlüsselwort wie oben verwendet werden - es ist in diesem Fall nicht austauschbar (Hinweis: In C ++ 17 sind in diesem Fall beide Schlüsselwörter zulässig) .typename
Sie müssen auch Folgendes verwenden, class
wenn Sie eine Vorlage explizit instanziieren:
template class Foo<int>;
Ich bin mir sicher, dass es andere Fälle gibt, die ich verpasst habe, aber das Fazit lautet: Diese beiden Schlüsselwörter sind nicht gleichwertig, und dies sind einige häufige Fälle, in denen Sie das eine oder das andere verwenden müssen.
template <typename T> typename Foo {};
, da Foo <T> definitiv eine Klasse ist.std::vector<int>::value_type
ist kein abhängiger Typ, Sie brauchen ihntypename
dort nicht - Sie brauchen ihn nur, wenn ein Typ von einem Vorlagenparameter abhängt, sagen wirtemplate<class T> struct C { typedef typename std::vector<T>::value_type type; };
param_t
ist kein abhängiger Typ. Abhängige Typen sind Namen, die von einem Vorlagenparameter abhängig sind , z. B.foo<param_t>::some_type
keine Vorlagenparameter selbst.typename
, das heißttemplate <typename> typename C
.GCC 5
, G ++ ermöglicht nun Typname in einem Template - Template - Parameter .Zum Benennen von Vorlagenparametern
typename
undclass
sind äquivalent. §14.1.2:typename
In einem anderen Kontext ist es jedoch möglich, Vorlagen zu verwenden, um den Compiler darauf hinzuweisen, dass Sie auf einen abhängigen Typ verweisen. §14.6.2:Beispiel:
Ohne
typename
den Compiler kann man im Allgemeinen nicht sagen, ob man sich auf einen Typ bezieht oder nicht.quelle
Obwohl es keinen technischen Unterschied gibt, habe ich gesehen, dass die beiden verwendet wurden, um leicht unterschiedliche Dinge zu bezeichnen.
Für eine Vorlage, die einen beliebigen Typ als T akzeptieren sollte, einschließlich integrierter Elemente (z. B. eines Arrays).
Für eine Vorlage, die nur funktioniert, wenn T eine echte Klasse ist.
Aber denken Sie daran, dass dies nur ein Stil ist, den manche Leute benutzen. Nicht vom Standard vorgeschrieben oder von Compilern durchgesetzt
quelle
T t; int i = t.toInt();
), benötigen Sie eine "echte Klasse", und Ihr Code wird nicht kompiliert, wenn Sieint
fürT
...class
impliziert, dass Sie nicht nur einen "Wert" erwarten, der möglicherweise einige Operatoren unterstützt, Konstruktionen und / oder Zuweisungen kopiert oder verschiebt, sondern speziell einen Typ benötigen, der eine Semantik des Mitgliederzugriffs unterstützt. Der schnellste Blick auf die Deklaration setzt dann Erwartungen und entmutigt, z. B. eingebaute Typen fürclass
Parameter bereitzustellen, wenn dies sicherlich ein Fehler wäre.Container
ist selbst eine Vorlage mit zwei Typparametern.quelle
template<template<class U> class V> struct C {};
Dieses Snippet stammt aus dem C ++ - Primer-Buch. Obwohl ich sicher bin, dass das falsch ist.
Vor jedem Typparameter muss die Schlüsselwortklasse oder der Typname stehen:
Diese Schlüsselwörter haben dieselbe Bedeutung und können innerhalb einer Vorlagenparameterliste austauschbar verwendet werden. Eine Vorlagenparameterliste kann beide Schlüsselwörter verwenden:
Es mag intuitiver erscheinen, das Schlüsselwort Typname anstelle der Klasse zu verwenden, um einen Vorlagentypparameter zu bestimmen. Schließlich können wir integrierte (Nichtklassen-) Typen als Vorlagentypargument verwenden. Darüber hinaus zeigt der Typname deutlicher an, dass der folgende Name ein Typname ist. Der Typname wurde jedoch zu C ++ hinzugefügt, nachdem Vorlagen bereits weit verbreitet waren. Einige Programmierer verwenden weiterhin ausschließlich Klassen
quelle