it-swarm.com.de

Was ist der Unterschied zwischen 'typedef' und 'using' in C ++ 11?

Ich weiß, dass wir in C++ 11 jetzt using verwenden können, um Typalias zu schreiben, wie typedefs:

typedef int MyInt;

Ist meines Wissens gleichbedeutend mit:

using MyInt = int;

Und diese neue Syntax entstand aus der Bemühung, "template typedef" auszudrücken:

template< class T > using MyType = AnotherType< T, MyAllocatorType >;

Gibt es bei den ersten beiden Beispielen, bei denen es sich nicht um Vorlagen handelt, noch weitere geringfügige Unterschiede im Standard? Zum Beispiel machen typedefs Aliasing auf "schwache" Weise. Das heißt, es wird kein neuer Typ erstellt, sondern nur ein neuer Name (Konvertierungen zwischen diesen Namen sind implizit).

Ist es dasselbe mit using oder generiert es einen neuen Typ? Gibt es da unterschiede

813
Klaim

Sie entsprechen der Norm (Schwerpunkt Mine) (7.1.3.2):

Ein typedef-Name kann auch durch eine Alias-Deklaration eingeführt werden. Der Bezeichner nach dem Schlüsselwort using wird zu einem typedef-Namen, und der optionale Attributbezeichner seq nach dem Bezeichner bezieht sich auf diesen typedef-Namen. Es hat die gleiche Semantik, als ob es vom Typedef-Spezifizierer eingeführt worden wäre. Insbesondere definiert es keinen neuen Typ und soll nicht in der Typ-ID erscheinen.

530
Jesse Good

Die sing - Syntax hat einen Vorteil, wenn sie in Vorlagen verwendet wird. Wenn Sie die Typabstraktion benötigen, aber auch die Vorlagenparameter beibehalten müssen, um sie in Zukunft angeben zu können. Sie sollten so etwas schreiben.

template <typename T> struct whatever {};

template <typename T> struct rebind
{
  typedef whatever<T> type; // to make it possible to substitue the whatever in future.
};

rebind<int>::type variable;

template <typename U> struct bar { typename rebind<U>::type _var_member; }

Aber sing Syntax vereinfacht diesen Anwendungsfall.

template <typename T> using my_type = whatever<T>;

my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }
190
4xy

Sie sind weitgehend gleich, mit der Ausnahme, dass:

Die Alias-Deklaration ist mit Vorlagen kompatibel, die C-Typedef-Deklaration dagegen nicht.

186
Zhongming Qu

Sie sind im Wesentlichen gleich, aber using liefert alias templates, was sehr nützlich ist. Ein gutes Beispiel, das ich finden könnte, ist wie folgt:

namespace std {
 template<typename T> using add_const_t = typename add_const<T>::type;
}

Also können wir std::add_const_t<T> anstelle von typename std::add_const<T>::type verwenden

24
Validus Oculus

Ich weiß, dass das Originalplakat eine gute Antwort hat, aber für jeden, der über diesen Thread stolpert, wie ich es habe, gibt es eine wichtige Anmerkung von dem Vorschlag , die meiner Meinung nach der Diskussion hier etwas Wertvolles hinzufügt, insbesondere zu Bedenken in die Kommentare dazu, ob das Schlüsselwort typedef in Zukunft als veraltet markiert oder aus Gründen der Redundanz/Alterung entfernt werden soll:

Es wurde vorgeschlagen, das Schlüsselwort typedef ... (erneut) zu verwenden, um Vorlagen-Aliase einzuführen:

template<class T>
  typedef std::vector<T, MyAllocator<T> > Vec;

Diese Notation hat den Vorteil, dass ein bereits bekanntes Schlüsselwort verwendet wird, um einen Typalias einzuführen. Es zeigt jedoch auch einige Nachteile, unter denen die Verwirrung, ein Schlüsselwort zu verwenden, das bekanntermaßen einen Alias ​​für einen Typnamen einführt, in einem Kontext, in dem der Alias ​​keinen Typ, sondern eine Vorlage bezeichnet; Vec ist kein Alias ​​für einen Typ und sollte nicht für einen Typedef-Namen verwendet werden. Der Name Vec ist ein Name für die Familie std::vector<•, MyAllocator<•> > - wobei das Aufzählungszeichen ein Platzhalter für einen Typnamen ist. Folglich schlagen wir die Syntax "typedef" nicht vor. Auf der anderen Seite der Satz

template<class T>
  using Vec = std::vector<T, MyAllocator<T> >;

kann gelesen/interpretiert werden als: Von nun an verwende ich Vec<T> als Synonym für std::vector<T, MyAllocator<T> >. Mit dieser Lesart erscheint die neue Syntax für das Aliasing einigermaßen logisch.

Für mich bedeutet dies, dass das Schlüsselwort typedef in C++ weiterhin unterstützt wird, da es den Code lesbarer und verständlicher machen kann .

Das Aktualisieren des Schlüsselworts using wurde speziell für Vorlagen durchgeführt, und (wie in der akzeptierten Antwort ausgeführt), wenn Sie mit Nicht-Vorlagen arbeiten. using und typedef sind mechanisch identisch Der Programmierer ist aufgrund der Lesbarkeit und der Mitteilung der Absicht völlig frei.

3
RoboticForest