it-swarm.com.de

Unterschied der Schlüsselwörter "Typname" und "Klasse" in Vorlagen?

Für Templates habe ich beide Deklarationen gesehen:

template < typename T >
template < class T >

Was ist der Unterschied?

Und was genau bedeuten diese Schlüsselwörter im folgenden Beispiel?

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

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 class gibt.

Der erste Fall betrifft abhängige Typen. typename wird verwendet, um zu deklarieren, wann Sie auf einen verschachtelten Typ verweisen, der von einem anderen Vorlagenparameter abhängt, z. B. typedef in diesem Beispiel:

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

Das zweite, das Sie tatsächlich in Ihrer Frage zeigen, obwohl Sie es möglicherweise nicht bemerken:

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

Wenn Sie ein Vorlagenvorlage angeben, MUSS das class-Schlüsselwort wie oben angegeben verwendet werden. In diesem Fall ist es nicht austauschbar mit typename (Anmerkung: seit C++ 17 sind in diesem Fall beide Schlüsselwörter zulässig) .

Sie müssen auch class verwenden, wenn Sie eine Vorlage explizit instanziieren:

template class Foo<int>;

Ich bin sicher, dass es andere Fälle gibt, die ich verpasst habe, aber das Fazit lautet: Diese beiden Schlüsselwörter sind nicht äquivalent, und dies sind einige häufige Fälle, in denen Sie das eine oder andere verwenden müssen.

379
Aaron Klotz

Zum Benennen von Vorlagenparametern sind typename und class äquivalent. §14.1.2:

Es gibt keinen semantischen Unterschied zwischen Klasse und Typname in einem Template-Parameter.

typename ist jedoch in einem anderen Kontext möglich, wenn Sie Vorlagen verwenden, um den Compiler darauf hinzuweisen, dass Sie auf einen abhängigen Typ verweisen. §14.6.2:

Es wird davon ausgegangen, dass ein in einer Vorlagendeklaration oder -definition verwendeter Name, der von einem Vorlagenparameter abhängig ist, einen Typ nicht benennt, es sei denn, die entsprechende Namenssuche findet einen Typnamen oder der Name wird durch das Schlüsselwort typname qualifiziert.

Beispiel:

typename some_template<T>::some_type

Ohne typename kann der Compiler im Allgemeinen nicht sagen, ob Sie sich auf einen Typ beziehen oder nicht.

80
Georg Fritzsche

Es gibt zwar keinen technischen Unterschied, aber ich habe gesehen, dass die beiden leicht unterschiedliche Dinge bezeichnen.

Für eine Vorlage, die einen beliebigen Typ als T akzeptieren soll, einschließlich eingebauter Elemente (z. B. ein Array)

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

Für eine Vorlage, die nur funktioniert, wenn T eine echte Klasse ist.

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

Aber denken Sie daran, dass dies ein Stil ist, den manche Leute verwenden. Nicht vom Standard vorgeschrieben oder von Compilern erzwungen

18
  1. Kein Unterschied
  2. Vorlagentypparameter Container ist selbst eine Vorlage mit zwei Typparametern.
6

Dieser Ausschnitt stammt aus dem C++ - Grundbuch. Obwohl ich mir sicher bin, dass das falsch ist.

Vor jedem Typparameter muss das Schlüsselwort class oder typename stehen:

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

Diese Schlüsselwörter haben dieselbe Bedeutung und können innerhalb einer Vorlagenparameterliste synonym verwendet werden. In einer Vorlagenparameterliste können beide Schlüsselwörter verwendet werden:

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

Es mag intuitiver erscheinen, den Schlüsselworttypnamen anstelle der Klasse zu verwenden, um einen Vorlagentypparameter zu bestimmen. Schließlich können wir eingebaute (nicht klassifizierte) Typen als Vorlagentypargument verwenden. Darüber hinaus zeigt 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 class

4
K.K