2016-05-25 20 views
5

Molto spesso nelle definizioni di classe C++, in particolare nelle biblioteche, di classe tratto ecc, si vede il codice simile al seguente frammento:Perché i parametri del modello typename non sono riconosciuti implicitamente come tipi?

template <typename Bar, typename Baz> 
class Foo { 
    using bar_type = Bar; 
    using baz_type = Baz; 
    // ... etc. 
} 

E solo con queste righe si può in seguito fare riferimento a Foo<A,B>::bar_type o Foo<C,D>:baz_type. Mi chiedo: perché lo standard del linguaggio non richiede che il compilatore definisca automaticamente i tipi usando i parametri del modello typename, ovvero consenti la rimozione delle due linee usando e riconosca Foo<A,B>::Bar come A e Foo<C,D>::Baz come D?

Questo non dovrebbe nemmeno violare il codice esistente, poiché all'interno di Foo, gli identificatori Bar e Baz sono già stati presi comunque.

+0

Perché potrebbero non essere tipi. Ad esempio, potrebbero essere un valore, ad esempio, N in 'template struct array' – davidbak

+5

Non sono sempre necessari e esponendoli significa che il codice client può essere accoppiato a loro (assumendo che tu significava che quegli alias erano pubblici.) – juanchopanza

+1

Un'altra risposta: perché è banale fare te stesso. Qual è stata la risposta data quando qualcuno ha chiesto perché non c'è una parola chiave 'super' in C++ (ma non ho il riferimento a quello a portata di mano). – davidbak

risposta

7

I nomi dei parametri non fanno parte dell'entità dichiarata. Questo è vero per entrambe le funzioni e i modelli. Il seguente codice dichiara solo due entità separate:

extern void f(int, char, bool); 
extern void f(int a, char b, bool c); 
extern void f(int x, char b, bool z); 

template <typename> struct X; 
template <typename A> struct X; 
template <typename T> struct X; 

nota in particolare che il seguente codice è perfettamente bene:

template <typename T> struct X { void f(); }; // X<T>::f not yet defined 
template <typename U> void X<U>::f() {}   // now it's defined 

Tutti i tentativi di deriva struttura aggiuntiva da nomi di parametro deve fare i conti con questa situazione. Una delle richieste più popolari in quest'area sono denominate parametri di funzione; ad oggi non c'è stata una proposta soddisfacente per tale estensione.

In una certa misura, tutte queste proposte richiederebbero che i nomi dei parametri fossero parte dell'entità dichiarata. Per le funzioni, ad esempio, ciò solleva la questione se i nomi dei parametri debbano essere storpiati ed esposti al linker.

+0

Chi lo sa. Una delle implicazioni nascoste dei nomi dei parametri che diventano parte delle firme delle funzioni potrebbe essere che ti apre a società come [Oracle] (https://en.wikipedia.org/wiki/Oracle_America,_Inc._v._Google,_Inc. citare il culo su di esso. –

+0

Sono ripetutamente scoraggiato da persone (non ovviamente) che sono in qualche modo infastidite da domande sul perché lo status quo è quello che è, e downvote o vota per chiudere senza commenti - quando c'è una risposta perfettamente ragionevole (che convalida la logica per la domanda.) – einpoklum

+0

@ einpoklum: Penso che questa sia una buona domanda e sono felice di aver letto la domanda e la risposta. Tuttavia, devo ammettere che quando l'ho letto per la prima volta, sono stato tentato di votare per chiudere, in quanto non pertinente allo stack overflow. La ragione per cui credo sia questa frase "E 'stato mai suggerito? Discusso? Respinto?" Non penso che le domande storiche arbitrarie su C++ facciano una buona domanda di SO - le domande dovrebbero riguardare la programmazione, e idealmente, di interesse per un programmatore che lavora, piuttosto che un accademico o storico, IMO. Senza quella linea, probabilmente lo voterò comunque. Sono solo un punto campione, YMMV. –

Problemi correlati