2014-12-13 9 views
5

Perché C++ 11 non hanno "typedef template", comePerché C++ 11 non ha un typedef di modello?

template<typename T> typedef std::vector<T, myalloc<T>> vec; 

Invece che permettono solo la nuova sintassi:

template<typename T> using vec = std::vector<T, myalloc<T>>; 
+0

Forse guardare attraverso i riferimenti elencati nella parte posteriore di [N2258] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf)? –

+0

Gli alias di modello erano una necessità introdotta in C++ 11 e si decise che si doveva usare 'using' invece di' typedef'. – 101010

+0

Poiché la sintassi 'typedef' è orribile (estende * la sintassi della dichiarazione delle variabili *!), Specialmente per i tipi di funzione. "usare" è molto più leggibile; a meno che tu non abbia davvero bisogno della compatibilità prima dell'11, basta sostituire tutti i typedefs con "using" e goderti quanto più pulito diventa il codice. – Griwes

risposta

8

n1406 è stata la proposta da Herb Sutter per "modelli typedef" che imita la sintassi nella tua domanda. n1499 che propone "alias modello" lo sostituisce, che contiene la sintassi using attualmente presente in C++ 11.

Uno dei principali inconvenienti dei "modelli typedef" è indicato in entrambi i documenti. Da n1406:

In pratica esistente, compreso nella libreria standard, nomi di tipo annidati dentro modelli di classi helper vengono utilizzati per ovviare a questo problema in molti casi. Di seguito è riportato un esempio di questa solita soluzione: ; lo svantaggio principale è la necessità di scrivere :: Type quando si utilizza il typedef'd name.

template< typename T > 
struct SharedPtr 
{ 
    typedef Loki::SmartPtr 
    < 
     T,    // note, T still varies 
     RefCounted,  // but everything else is fixed 
     NoChecking, 
     false, 
     PointsToOneObject, 
     SingleThreaded, 
     SimplePointer<T> // note, T can be used as here 
    > 
    Type; 
}; 

SharedPtr<int>::Type p; // sample usage, “::Type” is ugly 

Quello che ci piacerebbe davvero essere in grado di fare è semplicemente questo:

template< typename T > 
typedef Loki::SmartPtr 
    < 
    T,    // note, T still varies 
    RefCounted,  // but everything else is fixed 
    NoChecking, 
    false, 
    PointsToOneObject, 
    SingleThreaded, 
    SimplePointer<T> // note, T can be used as here 
    > 
    SharedPtr; 

SharedPtr<int> p;  // sample usage, “::Type” is ugly 

[...]

La soluzione è brutto, e sarebbe bene per sostituire con il supporto di lingua di prima classe che offre agli utenti una sintassi del modello C++ naturale .

Quel "supporto di lingua di prima classe" si presenta sotto forma di alias di modello. Possiamo ora guardare ciò n1499 ha da fare:

In questo articolo ci concentreremo sulla descrizione di un meccanismo di aliasing che permette alle due semantica menzionati N1406 coesistere essendo invece considerati come reciprocamente esclusivi. In primo luogo consideriamo un esempio giocattolo:

template <typename T> 
class MyAlloc {/*...*/}; 

template <typename T, class A> 
class MyVector {/*...*/}; 

template <typename T> 
struct Vec { 
typedef MyVector<T, MyAlloc<T> > type; 
}; 

Vec<int>::type p; // sample usage 

Il problema fondamentale con questo idioma, e le principali realtà motivante per questa proposta, è che il linguaggio fa sì che i parametri del modello di appaiono nel contesto non deducibili. Cioè, non sarà possibile chiamare nella funzione foo senza specificare esplicitamente gli argomenti del modello .

template <typename T> void foo (Vec<T>::type&); 

Inoltre, la sintassi è un po 'brutta. Preferiamo evitare la chiamata nidificata al numero ::. Preferiremmo qualcosa di simile al seguente:

template <typename T> 
using Vec = MyVector<T, MyAlloc<T> >; //defined in section 2 below 

Vec<int> p;  // sample usage 

noti che specificamente evitare il termine "typedef template" e presentiamo la nuova sintassi che coinvolge la coppia "con" e "=" per aiutare evitare confusione: abbiamo non sono definendo qualsiasi tipo qui, siamo introducendo un sinonimo (es.alias) per un'astrazione di un(ovvero un'espressione di tipo) che coinvolge i parametri del modello. Se si utilizzano i template parametri in contesti deducibili nell'espressione tipo poi ogniqualvolta l'alias modello viene utilizzato per formare un modello-id, i valori dei parametri del modello corrispondenti possono essere dedotte - altro su questa seguiranno. In ogni caso, è ora possibile scrivere le funzioni generiche che operano su Vec<T> in un contesto deducibile e la sintassi è anch'essa migliorata. Per esempio si potrebbe riscrivere foo come:

template <typename T> void foo (Vec<T>&); 

Sottolineiamo qui che uno dei motivi principali per proporre alias modello è stato in modo che la deduzione argomentazione e la chiamata alla foo(p) avrà successo.

Così si può vedere che n1499 risolve i problemi in n1406 e introduce una sintassi molto più pulita e facile da leggere.

+0

Perché 'template typedef MyVector > Vec;' non risolve il problema? – steveire

Problemi correlati