it-swarm.com.de

'Class' oder 'typename' für Vorlagenparameter verwenden?

Mögliches Duplikat:
C++ - Unterschied zwischen den Schlüsselwörtern "Typname" und "Klasse" in Vorlagen

Wenn Sie eine Funktions- oder Klassenvorlage in C++ definieren, können Sie Folgendes schreiben:

template <class T> ...

oder man kann das schreiben:

template <typename T> ...

Gibt es einen guten Grund, den einen dem anderen vorzuziehen?


Ich habe die beliebteste (und interessanteste) Antwort akzeptiert, aber die eigentliche Antwort scheint zu lauten: "Nein, es gibt keinen guten Grund, eine der anderen vorzuziehen."

  • Sie sind gleichwertig (außer wie unten angegeben).
  • Einige Leute haben Gründe, immer typename zu verwenden.
  • Einige Leute haben Gründe, immer class zu verwenden.
  • Einige Leute haben Gründe, beides zu benutzen.
  • Manche Leute kümmern sich nicht darum, welche sie benutzen.

Beachten Sie jedoch, dass vor C++ 17 im Fall von Template-Template -Parametern die Verwendung von class anstelle von typename erforderlich war. Siehe Antwort von user1428839 unten. (Aber dieser spezielle Fall ist keine Frage der Präferenz, er war eine Anforderung der Sprache.)

567

Stan Lippman hat darüber gesprochen hier . Ich fand es interessant.

Zusammenfassung : Stroustrup verwendete ursprünglich class, um Typen in Vorlagen anzugeben, um die Einführung eines neuen Schlüsselworts zu vermeiden. Einige im Ausschuss befürchteten, dass diese Überlastung des Keywords zu Verwirrung führen könnte. Später führte das Komitee ein neues Schlüsselwort typename ein, um syntaktische Mehrdeutigkeiten aufzulösen, und beschloss, es auch zur Angabe von Vorlagentypen zu verwenden, um Verwirrung zu vermeiden. Aus Gründen der Abwärtskompatibilität behielt class jedoch seine überladene Bedeutung bei.

387
itsmatt

Laut Scott Myers, Effective C++ (3. Aufl.), Punkt 42 (was natürlich die ultimative Antwort sein muss) - der Unterschied ist "nichts".

Es wird empfohlen, "class" zu verwenden, wenn dies erwartet wird. T wird immer eine Klasse sein, mit "typename", wenn andere Typen (int, char * was auch immer) erwartet werden können. Betrachten Sie es als Verwendungshinweis.

301
DarenW

Als Ergänzung zu allen obigen Beiträgen die Verwendung des Schlüsselworts class ist gezwungen (bis einschließlich C++ 14) im Umgang mit vorlage Vorlage Parameter, z.B.

template <template <typename, typename> class Container, typename Type>
class MyContainer: public Container<Type, std::allocator<Type>>
{ /*...*/ };

In diesem Beispiel hätte typename Container einen Compilerfehler erzeugt, etwa so:

error: expected 'class' before 'Container'
145
JorenHeit

Ich bevorzuge die Verwendung von typename, weil ich kein Fan überladener Keywords bin (jeez - wie viele verschiedene Bedeutungen hat static für verschiedene Kontexte?).

47
Michael Burr

Es gibt ist einen Unterschied, und Sie sollten class dem typename vorziehen.

Aber wieso?

typename ist für Template-Template-Argumente unzulässig. Um konsistent zu sein, sollten Sie class verwenden:

template<template<class> typename MyTemplate, class Bar> class Foo { };    //  :(
template<template<class>    class MyTemplate, class Bar> class Foo { };    //  :)
15
Mehrdad

Als Antwort auf Mike B bevorzuge ich die Verwendung von 'class', da 'typename' in einer Vorlage eine überladene Bedeutung hat, 'class' jedoch nicht. Nehmen Sie dieses Beispiel für einen aktivierten Integer-Typ:

template <class IntegerType>
class smart_integer {
public: 
    typedef integer_traits<Integer> traits;
    IntegerType operator+=(IntegerType value){
        typedef typename traits::larger_integer_t larger_t;
        larger_t interm = larger_t(myValue) + larger_t(value); 
        if(interm > traits::max() || interm < traits::min())
            throw overflow();
        myValue = IntegerType(interm);
    }
}

larger_integer_t ist ein abhängiger Name, daher muss ihm ein 'Typname' vorangestellt werden, damit der Parser erkennen kann, dass larger_integer_t ein Typ ist. Die Klasse hat dagegen keine überladene Bedeutung.

Das ... oder ich bin nur faul im Herzen. Ich tippe viel häufiger 'class' als 'typename' und finde es daher viel einfacher, zu tippen. Oder es könnte ein Zeichen dafür sein, dass ich zu viel OO Code schreibe.

9
Aaron

Nur reine Geschichte. Zitat von Stan Lippman :

Der Grund für die beiden Schlüsselwörter ist historisch. In der ursprünglichen Vorlagenspezifikation hat Stroustrup das vorhandene Schlüsselwort class erneut verwendet, um einen Typparameter anzugeben, anstatt ein neues Schlüsselwort einzuführen, das natürlich vorhandene Programme beschädigen könnte. Es war nicht so, dass ein neues Keyword nicht in Betracht gezogen wurde - nur, dass es aufgrund seiner möglichen Störung nicht als notwendig erachtet wurde. Bis zum ISO-C++ - Standard war dies die einzige Möglichkeit, einen Typparameter zu deklarieren.

Aber man sollte Typname anstelle von Klasse verwenden! Weitere Informationen finden Sie unter dem Link. Beachten Sie jedoch den folgenden Code:

template <class T>
class Demonstration { 
public:
void method() {
   T::A *aObj; // oops ...
};
9
user306683

Es spielt überhaupt keine Rolle, aber Klasse lässt es so aussehen, als ob T nur eine Klasse sein kann, während es natürlich jeder Typ sein kann. Der Typname ist also genauer. Auf der anderen Seite benutzen die meisten Leute den Unterricht, so dass das Lesen im Allgemeinen wahrscheinlich einfacher ist.

7

Soweit ich weiß, spielt es keine Rolle, welchen Sie verwenden. Sie sind in den Augen des Compilers gleichwertig. Verwenden Sie, was Sie bevorzugen. Ich benutze normalerweise Klasse.

1
Grant Limberg