2010-12-30 11 views
6

Va bene ho intenzione di dare un semplice esempio del mio problema:Perché non posso passare i parametri del modello su un altro modello?

void Increment(Tuple<int, int>& tuple) { 
    ++tuple.Get<0>(); 
} 

int main() { 

    Tuple<int, int> tuple; 

    tuple.Get<0>() = 8; 

    Increment(tuple); 

    printf("%i\n", tuple.Get<0>()); // prints 9, as expected 

    return 0; 

} 

Questo compila bene, e tutto è peachy. La funzione Increment incrementa solo il primo elemento della tupla, quindi stampo quell'elemento. Tuttavia, non sarebbe bello se la mia funzione Incremento potesse essere utilizzata su qualsiasi tipo di elemento?

template <typename T> 
void Increment(Tuple<T, T>& tuple) { 
    ++tuple.Get<0>(); // <-- compile ERROR 
} 

int main() { 

    Tuple<int, int> tuple; 

    tuple.Get<0>() = 8; 

    Increment<int>(tuple); 

    printf("%i\n", tuple.Get<0>()); 

    return 0; 

} 

Il mio secondo esempio sputa fuori il seguente errore al momento della compilazione:

error: expected primary-expression before ')' token 

Sono al mio ingegno fine cercando di capire perché questo provoca problemi. Poiché il parametro template è 'int', il codice generato deve essere identico a nell'esempio hard-coded. Come posso farlo funzionare?

+1

La bruttezza e accorgimenti di utilizzo come indicato nella risposta di Gman è probabilmente la ragione per la quale sia std e aumentare tuple hanno un libero 'funzione di GET':' ++ ottenere <0> (tuple); ' – UncleBens

risposta

11

dovrebbe essere:

++tuple.template Get<0>(); 

Allo stesso modo è necessario typename specificare un tipo qualificato da un tipo dipendente, è necessario template per specificare una funzione template qualificato da un tipo dipendente.

+0

Ha funzionato brillantemente! Non posso credere dopo tutti questi anni di utilizzo del C++ che non avevo mai sentito nominare. Suppongo che non utilizzi i modelli abbastanza spesso. Grazie! – nonoitall

+0

@nonoitall: è meno conosciuto, per qualche motivo. (Anche perché molte persone usano NSVC e funziona senza di esso, quindi le persone non incontrano mai il problema.) – GManNickG

+0

@Gman: Sì, è perché MSVC non lo richiede. – Puppy

4

Dal Gman già ti ha dato la corretta answer, una cosa si può ancora fare è: si può semplicemente scrivere Increment(tuple) invece di Increment<int>(tuple) (quest'ultimo sintassi è un po 'complessa). Il compilatore è abbastanza intelligente da dedurre il tipo di modello di funzione dal tipo di tuple.

vedere questo: http://www.ideone.com/juNOg

+0

Buono per un commento. Sospetto che sia una presa di posizione da parte sua provare diverse cose per farlo funzionare. – GManNickG

Problemi correlati