Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++, rvalue references in function parameters

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?

like image 290
CarlosHD Avatar asked May 20 '15 03:05

CarlosHD


People also ask

When should a function take rvalue reference?

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 .

Can a function return an rvalue?

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.

Can you pass an lvalue to an rvalue reference?

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.

What is R value Referene in C ++ 11?

“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.


1 Answers

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.

like image 196
songyuanyao Avatar answered Sep 24 '22 04:09

songyuanyao