2012-05-25 8 views
598

So che in C++ 11 ora possiamo usare using di scrivere tipo alias, come typedef s:Qual è la differenza tra "typedef" e "using" in C++ 11?

typedef int MyInt; 

è, da quanto ho capito, equivalente a:

using MyInt = int; 

E questo nuova sintassi emerso dallo sforzo di avere un modo per esprimere "template typedef":

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

Ma, con i primi due non-t esemplificare esempi, ci sono altre sottili differenze nello standard? Ad esempio, typedef s fa l'aliasing in un modo "debole". Cioè non crea un nuovo tipo ma solo un nuovo nome (le conversioni sono implicite tra quei nomi).

È lo stesso con using o genera un nuovo tipo? Ci sono delle differenze?

+145

Io personalmente preferisco la nuova sintassi, perché è molto più simile a regolare l'assegnazione variabili, migliorando la leggibilità. Ad esempio, preferisci 'typedef void (& MyFunc) (int, int);' oppure 'using MyFunc = void (int, int);'? –

+3

Concordo pienamente, uso solo la nuova sintassi ora. Ecco perché lo stavo chiedendo, per essere sicuro che non ci fosse davvero alcuna differenza. – Klaim

+56

@MatthieuM. questi due sono diversi tra loro. Dovrebbe essere 'typedef void MyFunc (int, int);' (che in realtà non sembra così male), o 'using MyFunc = void (&) (int, int);' –

risposta

401

sono equivalenti, da quella standard (sottolineatura mia) (7.1.3.2):

Un nome-typedef può essere introdotto anche da un alias-dichiarazione. L'identificatore che segue la parola chiave using diventa un typedef-name e l'attributo-specifier-seq opzionale che segue l'identificatorea quel typedef-name. Ha la stessa semantica come se fosse introdotta dall'identificatore typedef. In particolare, lo non definisce un nuovo tipo e non deve apparire nell'id del tipo.

+14

Dalla risposta, la parola chiave 'using' sembra essere un superset di' typedef'. Quindi, 'typdef' sarà deprecato in futuro? – iammilind

+0

Questo lo rende chiaro. – Klaim

+4

@iammilind probabilmente no, ma puoi codificarlo come se lo fosse. – bames53

139

Il utilizzando la sintassi ha un vantaggio quando viene utilizzato all'interno dei modelli. Se è necessaria l'astrazione del tipo, ma è anche necessario mantenere in futuro il parametro del modello da specificare. Dovresti scrivere qualcosa come questo.

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; } 

Ma utilizzando la sintassi semplifica questo caso d'uso.

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

my_type<int> variable; 
template <typename U> struct baz { my_type<U> _var_member; } 
+20

Ho già indicato questo nella domanda però. La mia domanda è se non si utilizza il modello ci sono differenze con typedef. Ad esempio, quando usi "Foo foo {init_value};" invece di "Foo foo (init_value)" si suppone che entrambi facciano la stessa cosa ma non rispettino esattamente le stesse regole. Quindi mi chiedevo se esistesse una differenza nascosta simile con l'utilizzo di/typedef. – Klaim

101

Essi sono in gran parte lo stesso, solo che

The alias declaration is compatible with templates, whereas the C style typedef is not.

+12

Particolarmente affezionato alla semplicità della risposta e sottolineando l'origine della composizione. – g24l