I'm trying to understand rvalue
references. I have seen how they are used in constructors, with things like std::move
and std::forward
, but I still don't understand why this doesn't work:
void func(string&& str)
{
cout << str << endl;
}
int main(int argc, char* argv[])
{
string s("string");
func(s);
}
And this does:
template<typename T>
void func(T&& str)
{
cout << str << endl;
}
int main(int argc, char* argv[])
{
string s("string");
func(s);
}
Why does it work with the function template version?
Rvalue References As Return Types So it is only really applicable if you're returning something like member variables or reference parameters and you're moving them out of place. There is only one function that moves a reference parameter out: std::move .
Typically rvalues are temporary objects that exist on the stack as the result of a function call or other operation. Returning a value from a function will turn that value into an rvalue. Once you call return on an object, the name of the object does not exist anymore (it goes out of scope), so it becomes an rvalue.
In the example, the main function passes an rvalue to f . The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g ). You can cast an lvalue to an rvalue reference.
“l-value” refers to a memory location that identifies an object. “r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable. They are declared using the '&' before the name of the variable.
Like @Peter said, the type of T
is deduced as string&
, and C++’s reference-collapsing rule says:
T& & ⇒ T& // from C++98
T&& & ⇒ T& // new for C++0x
T& && ⇒ T& // new for C++0x
T&& && ⇒ T&& // new for C++0x
So func
’s instantiation is actually:
void func(string& str)
And it works.
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