2016-04-27 4 views
1

Ich habe keine Ahnung, warum Compiler mir Warnungen über Template Instanziierungen gibt.Std :: Forward mit Template überladen Funktion

Das ist ein Stück Code, der einfach gut läuft und gibt lvalue/R-Wert richtig:

//template<typename T> 
void overloaded(const /*T*/std::string& in) 
{ 
    std::cout << "lvalue" << std::endl; 
} 

//template<typename T> 
void overloaded(/*T*/std::string&& in) 
{ 
    std::cout << "rvalue" << std::endl; 
} 

template<typename T> 
void pass(T&& in) 
{ 
    overloaded(std::forward<T>(in)); 
} 

int main() 
{ 
    std::string a; 
    pass(a); 
    pass(std::move(a)); 
    getchar(); 
} 

Aber ich brauche es mit Templat-Typ zu verwenden. So Modifizierung der „überlastet“ Funktionen

template<typename T> 
void overloaded(const T& in) 
{ 
    std::cout << "lvalue" << std::endl; 
} 

template<typename T> 
void overloaded(T&& in) 
{ 
    std::cout << "rvalue" << std::endl; 
} 

Gibt Warnungen Vorlage instantiations, (wenn mir seine klare T std werden sollte :: string) und Konsole ausgibt rvalue 2mal statt lvalue zuerst.

Was mache ich falsch?

+0

Funktioniert für mich. http://coliru.stacked-crooked.com/a/fc00c140c9a8e208 – erip

+0

'T &&' ist eine Forwarding-Referenz, dh wenn 'T' ein Typ Template-Parameter ist, ist es nicht mehr ein regulärer Rvalue-Referenz –

Antwort

1

Vorlagen wie T&& sind speziell. Sie werden als "Weiterleitungsreferenzen" bezeichnet. Sie haben spezielle Abzugsregeln für Funktionen wie:

template<typename T> 
void overloaded(T&& in) 

für einen Moment wird angenommen, dass overloaded nicht überlastet wird. Wenn Sie einen Lvalue-Ausdruck vom Typ std::string an overloaded übergeben, wird T als std::string& abgeleitet. Wenn Sie einen rvalue-Ausdruck des Typs std::string an overloaded übergeben, wird T auf std::string ableiten. Dieses Wissen können Sie dies tun verwenden:

template<typename T> 
void overloaded(T&& in) 
{ 
    if (std::is_lvalue_reference<T>::value) 
     std::cout << "lvalue" << std::endl; 
    else 
     std::cout << "rvalue" << std::endl; 
} 

Im Allgemeinen ist es ein Anti-Muster T&& Vorlagen mit irgendetwas anderes zu überlasten. Diese speziellen Vorlagen sind praktisch, wenn Sie alles fangen wollen.

+0

Wow, ich war mir völlig nicht bewusst davon! Vielen Dank! – Pancake

Verwandte Themen