2012-11-29 7 views
7

Considerate questo codice:modello di argomentazione perde un riferimento lvalue, se non utilizzati direttamente

#include <iostream> 
#include <type_traits> 
using namespace std; 

template<typename T_orig> void f(T_orig& a){ 
    a=5; 
} 


template<typename T_orig, typename T=T_orig&> void g(T a){ 
    a=8; 
} 

int main() { 
    int b=3; 
    f<decltype(b)>(b); 
    cout<<b<<endl; 
    g<decltype(b)>(b); 
    cout<<b<<endl; 
    return 0; 
} 

Questo stampa

5 
5 

Qualcuno può spiegarmi perché nella seconda versione del & è perduto?

+2

Btw, 'ternary_op' assomiglia molto a' std :: condizionale'. –

+2

Questa è una versione semplificata, fondamentalmente la stessa: http://ideone.com/9DSsfb – mfontanini

risposta

12

Il problema qui è che la deduzione di tipo ha la priorità sui parametri del modello di funzione predefiniti. Pertanto si ottiene il parametro T dedotto e T non deduce mai un riferimento.

È possibile evitare questo rendendo il tipo not deducible. Un tratto del tipo di identità generico può farlo.

template <typename T> 
struct identity { using type = T; }; 

template <typename T> 
using NotDeducible = typename identity<T>::type; 

template<typename T_orig, typename T=typename target<T_orig>::T> 
void g(NotDeducible<T> a) { // blah 

Oppure, in questo caso particolare, è possibile semplicemente eliminare completamente il parametro del modello.

template<typename T_orig> void g(typename target<T_orig>::T a) 
+1

non si finisce mai di imparare. –

Problemi correlati