Ich weiß, dass wir in C ++ 11 jetzt Typalias using
schreiben können, wie typedef
s:
typedef int MyInt;
Ist nach meinem Verständnis gleichbedeutend mit:
using MyInt = int;
Und diese neue Syntax entstand aus dem Bestreben heraus, " template typedef
" auszudrücken :
template< class T > using MyType = AnotherType< T, MyAllocatorType >;
Gibt es bei den ersten beiden Beispielen ohne Vorlage noch andere subtile Unterschiede im Standard? Zum Beispiel führen typedef
wir Aliasing auf "schwache" Weise durch. Das heißt, es wird kein neuer Typ erstellt, sondern nur ein neuer Name (Konvertierungen sind zwischen diesen Namen implizit).
Ist es dasselbe mit using
oder generiert es einen neuen Typ? Gibt es Unterschiede?
c++
c++11
typedef
using-declaration
Klaim
quelle
quelle
typedef void (&MyFunc)(int,int);
oderusing MyFunc = void(int,int);
?typedef void MyFunc(int,int);
(was eigentlich nicht so schlecht aussieht), oderusing MyFunc = void(&)(int,int);
using MyFunc = void(&)(int,int);
? Bedeutet das, dass es sichMyFunc
um einen Verweis auf eine Funktion handelt? Was ist, wenn Sie das & weglassen ?typedef void (&MyFunc)(int,int);
. Wenn Sie das weglassen, ist&
es gleichbedeutend mittypedef void MyFunc(int,int);
Antworten:
Sie entsprechen dem Standard (Schwerpunkt Mine) (7.1.3.2):
quelle
using
Schlüsselwort eine Obermenge von isttypedef
. Dann wirdtypdef
in Zukunft veraltet sein?using
Syntax genau deshalb eingeführt haben , weil dietypedef
Semantik mit Vorlagen nicht gut funktioniert hat. Was irgendwie der Tatsache widerspricht, dassusing
genau dieselbe Semantik definiert ist.n1489
. Ein Vorlagenalias ist kein Alias für einen Typ, sondern ein Alias für eine Gruppe von Vorlagen. Um zwischentypedef
dem empfundenen Bedürfnis nach neuer Syntax zu unterscheiden. Beachten Sie auch, dass sich die Frage des OP auf den Unterschied zwischen Nicht-Vorlagenversionen bezieht.typdef
ich jemals veraltet bin .Sie sind weitgehend gleich, außer dass:
quelle
typedef
wenn ich fragen darf?Die Verwendung der Syntax hat einen Vorteil, wenn sie in Vorlagen verwendet wird. Wenn Sie die Typabstraktion benötigen, aber auch den Vorlagenparameter beibehalten müssen, damit er in Zukunft angegeben werden kann. Sie sollten so etwas schreiben.
Die Verwendung der Syntax vereinfacht diesen Anwendungsfall.
quelle
Sie sind im Wesentlichen gleich,
using
bieten aber,alias templates
was sehr nützlich ist. Ein gutes Beispiel, das ich finden könnte, ist wie folgt:Also können wir
std::add_const_t<T>
statt verwendentypename std::add_const<T>::type
quelle
Ich weiß, dass das Originalposter eine großartige Antwort hat, aber für jeden, der über diesen Thread stolpert, wie ich, gibt es einen wichtigen Hinweis aus dem Vorschlag , der meiner Meinung nach der Diskussion hier etwas Wertvolles hinzufügt, insbesondere zu Bedenken in den Kommentaren darüber, ob das
typedef
Schlüsselwort lautet wird in Zukunft als veraltet markiert oder als überflüssig / alt entfernt entfernt:Für mich bedeutet dies, dass das
typedef
Schlüsselwort in C ++ weiterhin unterstützt wird, da es den Code immer noch lesbarer und verständlicher machen kann .Das Aktualisieren des
using
Schlüsselworts erfolgte speziell für Vorlagen und (wie in der akzeptierten Antwort ausgeführt), wenn Sie mit Nicht-Vorlagen arbeitenusing
undtypedef
mechanisch identisch sind. Die Wahl liegt also ganz im Sinne des Lesers und der Absichtskommunikation .quelle
Beide Schlüsselwörter sind gleichwertig, es gibt jedoch einige Einschränkungen. Zum einen ist das Deklarieren eines Funktionszeigers mit
using T = int (*)(int, int);
klarer als mittypedef int (*T)(int, int);
. Zweitens ist das Template-Alias-Formular mit nicht möglichtypedef
. Drittens würde das Offenlegen der C-APItypedef
in öffentlichen Headern erforderlich sein .quelle
Typedef-Deklarationen können als Initialisierungsanweisungen verwendet werden, während Alias-Deklarationen nicht verwendet werden können
Obwohl es sich um einen Eckfall handelt , ist eine typedef-Deklaration eine init-Anweisung und kann daher in Kontexten verwendet werden, die Initialisierungsanweisungen ermöglichen
während eine Alias-Deklaration ist nicht eine init-Anweisung , und somit kann nicht in einem Kontext verwendet werden , die ermöglicht Initialisierungsanweisungen
quelle