Consider the following toy code:
class X
{
public:
X() { }
X(X&& x) { }
X f1()
{
return *this; // error: rvalue reference to type X cannot bind to lvalue of type X
// ^^^^^^
}
};
X f2()
{
static X x;
return x; // error: rvalue reference to type X cannot bind to lvalue of type X
// ^^^^^^
}
X f3()
{
X x; // in my understanding, the name x defined here is lvalue since variable expressions are lvalues
return x; // this is OK, hence I think x in return statement becomes rvalue
}
From the toy code shown above, I found that the expression in return statement used to construct the temporary returned by a function "remains" to be treated as lvalue if it is a reference or a static local variable while the expression "changes" to rvalue if it is a local variable. Apology for my understanding to be poor and flawed since I'm really new to concepts related to rvalue/lvalue in C++...
My question: generally speaking, what are the rules for expression in return statement to be rvalue/lvalue? How exactly is the lvalue/rvalue property of an expression "changes" when it is put in a return statement?
The error messages above are given by Resharper C++ when it tries to see if the move constructor can be applied. The aim for me to write the above code was just to see whether the expression in return statement is treated as rvalue or as lvalue.