2015-03-11 10 views
7

Se ho bisogno di definire una funzione template foo con un parametro di modello-modello, di solito faccio la seguente:C'è qualche utilità per i parametri denominati in template Parametri

// Notice that the template parameter of class T is unnamed. 
template <template <typename> class T> void f() { std::cout << "Yay!\n"; } 

Si noti che il parametro di modello della parametro di modello-modello è senza nome, ma possiamo assegnare un nome a questo parametro:

// Now the template parameter of class T is named INNER. 
template <template <typename INNER> class T> void f(const INNER &inner) 
{ std::cout << inner << " Yay!\n"; } 

questo non sembra essere utile a tutti, perché non posso reffer il parametro INNER nella funzione, il codice precedente produce il seguente errore:

error: 'INNER' does not name a type

mi sorprende che la typename INNER non nomina un tipo, dopo tutto la parola chiave typename è lì, al fine di nominare un tipo. Comunque, questo è facile da risolvere però:

// Now INNER is the name of the template parameter of class T and also 
// the name of the second template parameter of foo. 
template <template <typename INNER> class T, typename INNER> void f(const INNER &inner) 
{ std::cout << inner << " Yay!\n"; } 
// ... 
f<std::valarray, int>(666); // Prints "666 Yay!" 

Ma alla fine, il parametro INNER non ha bisogno di un nome, dopo tutto:

// Now the template parameter of class T is unnamed one more time, 
// INNER is the name of the second template parameter of foo. 
template <template <typename> class T, typename INNER> void f(const INNER &inner) 
{ std::cout << inner << " Yay!\n"; } 
// ... 
f<std::valarray, int>(666); // Prints "666 Yay!" 

E (sicuro che già notato prima di me) il il nome nel parametro del modello template-template è ignorato! Sicuramente è stato ignorato perché altrimenti dovrebbe avere un nome-scontro con il secondo parametro template di foo, no?

Un'altra dimostrazione del nome del parametro del parametro di template-template essere ignorato:

// Now T is the name of the template parameter of class T and also 
// the name of the template parameter of foo! 
template <template <typename T> class T> void f() 
{ std::cout << "Yay!\n"; } 
// ... 
f<std::valarray>(); // prints "Yay!" 

Il tipo di nome T viene utilizzato dal parametro modello-modello e dallo stesso modello-modello al contemporaneamente? Io non la penso così, il nome nel parametro template template è ignorato AFAIK.

Quindi, qual è la domanda?

  1. Le mie ipotesi sono corrette? I nomi dei parametri del modello con nome dei parametri modello modello vengono ignorati?
  2. Se mi sbaglio e ho frainteso l'intera cosa, c'è un uso per i parametri denominati nei parametri template template? Puoi fornire alcuni esempi utili?

Per quanto riguarda esempi utili su 2 # mi riferisco a qualcosa che solo potrebbe essere raggiunto utilizzando i parametri del modello di nome di parametri di modello-modello.

+0

Penso che la lettura attraverso questo QA: http://stackoverflow.com/questions/213761/what-are-some-uses-of-template-template-parameters-in-c aiuterà a guidare perché non ci sarebbe alcun uso nel nominare il parametro template template.I TTP stanno essenzialmente dichiarando la firma di un argomento basato su modelli, non fornendo il metodo basato su modelli con argomenti di template aggiuntivi. Simile a quando si dichiara un functor, è '(* foo) (type, type type)', non '(* foo) (tipo nome, tipo nome, tipo nome)'. – aruisdante

risposta

8

[basic.scope.temp]/p1:

The declarative region of the name of a template parameter of a template template-parameter is the smallest template-parameter-list in which the name was introduced.

(Ora provare a dire che 10 volte.)

Può essere utilizzato all'interno di tale lista. Per esempio,

template < template<class T, T t> class TP > class foo {}; 
//       ^^-----T's scope ends here 
//       | 
//       T can be used here 

foo<std::integral_constant> bar; 
+0

Questo è molto simile alle dichiarazioni di funzione, tra l'altro. Quanto segue illustra l'analogia producendo un errore del compilatore: 'void f (int x, decltype (x)); int main() {f (1, nullptr); } '. Il seguente compila e collega bene: 'void f (int x, decltype (x)); int main() {f (1, 1); } void f (int, int) {} '. Questo perché l'ambito di 'x' è sufficiente per comprendere il' decltype' che viene dopo. –

+0

Ok, quindi mi sono sbagliato: il parametro named del parametro template-template non è ignorato, semplicemente non esiste al di fuori della sua classe template-template ... l'unico uso che posso pensare dei parametri template-template nominati è il seguente: 'template