2016-12-19 3 views
1

Wenn ich Effective Modern C++ by Scott Meyer darüber gelesen habe, wie die Funktion std :: forward funktioniert, habe ich eine Frage, die ich nicht ganz verstehe. Sprich, wenn wir eine Funktion foo haben wie folgt:C++ Übergabe von Rvalue-Referenz an Funktionen, die Lvalue-Referenz

template<typename T> 
void foo(T&& fooParam) 
{ 
    ... 
    someFunc(std::forward<T>(fooParam)); 
} 

In dem Buch erklärt Scott, dass die std::forward<T> in der folgenden Art und Weise umgesetzt werden könnte:

template<typename T> 
T&& forward(typename remove_reference<T>::type& param) 
{ 
    return static_cast<T&&>(param); 
} 

das Argument foo gibt Angenommen ist ein R-Wert vom Typ Widget. Dann wird die std::forward Funktionsvorlage würde wie folgt initialisiert werden:

Widget&& forward(Widget& param) 
{ return static_cast<Widget&&>(param); } 

Also meine Frage ist, wenn fooParam (die vom Typ Widget &&) weitergegeben std::forward, wie könnte die Funktion, die einen Parameter vom Typ Widget& param Match nimmt fooParam? Ich weiß, fooParam selbst ist ein Lvalue. Aber sein Typ ist immer noch rvalue Referenz (Widget &&) oder? Wie können sie zueinander passen?

Wenn eine Funktion, die einen Parameter des Lvalue-Referenztyps akzeptiert, mit einer Rvalue-Referenz übergeben werden könnte, könnte diese Funktion sogar den übergebenen Rvalue modifizieren (wie ein temporäres Objekt). Das macht keinen Sinn für mich machen ...

+0

Es ist die Anruferseite, die mit der Implikation der Weitergabe von Rvales betroffen sein sollte. Wenn rvalue an eine Funktion übergeben wird, sollte der Aufrufer der Funktion sie nicht weiter verwenden. Die Funktion, die den R-Wert empfängt, sieht den Parameter jedoch nur als normalen Wert. – sameerkn

Antwort

2
#include <iostream> 
using std::cout; 
using std::endl; 

template<class T> 
void my_print(T&& arg) 
{ 
    my_print_impl(std::forward<T>(arg)); 
} 
template<class T> 
void my_print_impl(T& arg) 
{ 
    cout << "lvalue reference" << endl; 
} 

template<class T> 
void my_print_impl(T&& arg) 
{ 
    cout << "rvalue reference" << endl; 
} 

int main() 
{ 
    int i = 1; 
    int & l_ref = i; 
    int && r_ref = 1; 
    my_print(l_ref);   //print lvalue reference 
    my_print(r_ref);   //print lvalue reference 
    my_print(std::move(l_ref)); //print rvalue reference 
    my_print(1);    //print rvalue reference, 1 is a true rvalue 
    system("pause"); 

    return 0; 
} 

Wie Sie sagen, r_ref ist ein L-Wert-Referenz, sollten Sie nicht machen es als R-Wert übereinstimmen reference.If Sie Parameter als rvalue Referenz, Verwendung geben wollen std::move() oder übergeben Sie einfach rvalue an Ihre Funktion.

Verwandte Themen