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

  • A+

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?


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);


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: