Frage zu perfect forwarding
-
Hallo,
Warum geht perfect forwarding in C++11 eigentlich nur in verbindung mit Templates?
template<class _T, class _D> std::pair<vec,vec> make_pair1(_T &&a, _T &&b) { return std::pair<_T, _D>( std::forward<_T>(a), std::forward<_D>(b) ); }typedef std::vector<int> vec; std::pair<vec,vec> make_pair2(vec &&a, vec &&b) { return std::pair<vec, vec>( std::forward<vec>(a), std::forward<vec>(b) ); }vec X = {1,2,3}; auto x = make_pair1(X, vec{ 2,3,3} ); //(1) auto x = make_pair2(X, vec{ 2,3,3} ); //(2)Variante 2 geht aber Variante 1 beschwert sich, dass vec nicht nach vec&& umgewandelt werden kann.
Die Templates ersetzen doch nur die Bezeichner, oder?
-
Perfect forwarding ist ein Nebeneffekt von "reference collapsing". Den gleichen Effekt kannst du auch mit typedef oder auto erreichen (damit lässt sich leider kein perfect forwarding erreichen, aber es passiert das Gleiche.)
http://stackoverflow.com/questions/4425182/question-about-c0x-reference-collapse
Sehr schönes Video von Meyers, da wird alles im Detail erklärt:
http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in-Cpp11
-
Das Perfect Forwarding ist gewissermassen ein Hack mit den RValues:
template<class _T, class _D> std::pair<vec,vec> make_pair1(_T &&a, _T &&b) auto x = make_pair1(X, vec{ 2,3,3} ); // _T = P& && => P& // _D = P&& && => P&& auto x = make_pair1(X, X); // _T = P& && => P& // _D = P& && => P&Das ganze läuft somit auf 2 verschiedene Instanzierungen der Funktion hinaus, und das geht nur mit Templates.
Die Verwandlung P& && => P& nennt sich Reference Collapsing (googlebar).
Vielleicht interessant: http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in-Cpp11Halte dich im Übrigen von Bezeichnern wie _T und _D fern, das sind reservierte Bezeichner, die du eigentlich nicht verwenden darfst.
Hmm, jetzt war das Küchlein etwas schneller.
-
std__forward schrieb:
Warum geht perfect forwarding in C++11 eigentlich nur in verbindung mit Templates?
Weil man zur Compile-Zeit wissen muss, was man für ein Argument hatte (Typ und Wert-Kategorie). Ohne dies wird es unmöglich das Ding an die richtige Funktion weiterzuleiten, da letztere überladen sein kann.
-
In letzter zeit werden vermehrt (wie ich finde) ziemlich coole videos verlinkt. Vielleicht wärs mal cool ne liste mit videos zu machen

-
Danke an alle die geantwortet haben.
Das Video werde ich mir anschauen, wenn ich irgendwann Zeit habe.
reference collapsing kannte ich noch gar nicht, klärt aber einiges.
-
fürwahr schrieb:
template<class _T, class _D> std::pair<vec,vec> make_pair1(_T &&a, _D &&b) auto x = make_pair1(X, vec{ 2,3,3} ); // _T = P& && => P& // _D = P&& && => P&&Das stimmt so nicht ganz. _D ist keine Rvalue-Referenz.
-
videoman schrieb:
In letzter zeit werden vermehrt (wie ich finde) ziemlich coole videos verlinkt. Vielleicht wärs mal cool ne liste mit videos zu machen

Äh, schon mal ins Video-Board geguckt?
