I came across the following example while attempting to understand what std::forward
does
// 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;
}
The output of the program is
calling fn with rvalue: [lvalue][rvalue]
Now my question is how did we get lvalue
first ? Here is my line of thought
in our main
I called fn(0);
Now 0 is rvalue. So the universal reference x is deduced to the following
void fn (int&& && x);
Now according to reference collapsing we would get
void fn (int&& x);
Thus making x
behave like an rvalue.So if x
is passed then rvalue overloaded method should be called. However it seems the other overloaded lvalue reference function is called. I would appreciate it if someone could clarify this
A named variable is NEVER an rvalue. It is invariably an lvalue. Rvalues are only pure expressions which don't have names.
int && i = int(0);
Here the expression int(0)
is an rvalue, but the variable i
itself is an lvalue, declared to be binding to an rvalue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With