Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between an ordinary rvalue reference and one returned by std::forward?

I can't do this:

int &&q = 7;
int &&r = q; 
//Error Message:
//cannot convert from 'int' to 'int &&'
//You cannot bind an lvalue to an rvalue reference

If I understand correctly, when initializing an rvalue reference, there's a temporary variable got initialized too. So int &&q = 7; can be considered as:

int temp = 7;
int &&q = temp;

And when using a reference on the right side, I am actually using the referee. So int &&r = q; can be considered as:

int &&r = temp;  //bind an lvalue to an rvalue reference, cause error, understandable

So above is how I understand the compiler error occurs.


Why adding std::forward can solve that?

int &&q = 7;
int &&r = std::forward<int>(q);

I know the std::forward always returns an rvalue reference, how is the reference returned by std::forward different from int&&q?

like image 945
Rick Avatar asked Aug 24 '18 06:08

Rick


People also ask

What is the use of std :: forward?

std::forward If arg is an lvalue reference, the function returns arg without modifying its type. This is a helper function to allow perfect forwarding of arguments taken as rvalue references to deduced types, preserving any potential move semantics involved.

What is forwarding reference in C++?

When t is a forwarding reference (a function argument that is declared as an rvalue reference to a cv-unqualified function template parameter), this overload forwards the argument to another function with the value category it had when passed to the calling function.

What is the difference between lvalue and rvalue references?

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

Can you pass an rvalue by reference?

You can pass an object to a function that takes an rvalue reference unless the object is marked as const . The following example shows the function f , which is overloaded to take an lvalue reference and an rvalue reference.


1 Answers

how is the reference returned by std::forward different from int&&q ?

Their value categories are different. And note that types and value categories are different things.

q is a named variable, it's qualified as lvalue, so it can't be bound to rvalue reference.

(emphasis mine)

the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as std::cin or std::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;

While rvalue reference returned from function is qualified as xvalue, which belongs to rvalue.

a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as std::move(x);

like image 196
songyuanyao Avatar answered Oct 20 '22 04:10

songyuanyao