2014-05-12 6 views
5

ich auf das folgende Beispiel kam bei dem Versuch, zu verstehen, was std::forward tutunderstading diese perfekte Forwarding Beispiel

// forward example 
#include <utility>  // std::forward 
#include <iostream>  // std::cout 

// function with lvalue and rvalue reference overloads: 
void overloaded (const int& x) {std::cout << "[lvalue]";} 
void overloaded (int&& x) {std::cout << "[rvalue]";} 

// function template taking rvalue reference to deduced type: 
template <class T> void fn (T&& x) { 
    overloaded (x);     // always an lvalue 
    overloaded (std::forward<T>(x)); // rvalue if argument is rvalue 
} 

int main() { 

    std::cout << "calling fn with rvalue: "; 
    fn (0); 
    std::cout << '\n'; 

    return 0; 
} 

Die Ausgabe des Programms ist

Telefonieren mit rvalue fn: [L-Wert] [rvalue ]

Jetzt ist meine Frage, wie haben wir zuerst lvalue bekommen? Hier ist mein Gedankengang in unserem main Ich rief fn(0); Jetzt 0 ist rvalue. So ist die universelle Referenz x wird auf die folgende

abgeleitet
void fn (int&& && x); 

nun nach Referenz kollabiert wir

void fn (int&& x); 

So machen x verhalten sich wie ein rvalue.So bekommen würde, wenn x dann sollte rvalue überladene Methode übergeben wird heißen. Es scheint jedoch, dass die andere überladene Lvalue-Referenzfunktion aufgerufen wird. Ich würde es schätzen, wenn jemand dies klären könnte

+2

'x' selbst ist ein Lvalue. 'x = 2;' ist vollkommen legal. Das kann man nicht mit einem rvalue machen. – chris

Antwort

3

Eine namens Variable ist NIE ein Rvalue. Es ist immer ein Wert. Rvalues ​​sind nur reine Ausdrücke, die keine Namen haben.

int && i = int(0); 

Hier ist der Ausdruck int(0) ist ein R-Wert, aber die Variable i selbst ist ein L-Wert, zu einem R-Wert als verbindlich erklärt.