binding an rvalue reference to an lvalue reference using move()

Hi guys, I just encountered a few problems regarding the usage of move() function.
1. Normally, the compiler forbids users to bind an lvalue(include an rvalue reference which is an lvalue itself) to an rvalue reference, such as the code below, which would generate a error.

 
int &&a = 1, &&b = a;

However, when I used move() function to convert an lvalue to an rvalue reference, then surprisingly I managed to bind an converted rvalue reference to another one.
 
    int &&a = 1, &&b = move(a);

why?

2. As shown in the code below, by using move()funciton, when I bound a converted lvalue to an rvalue reference, and then changed the value of the rvalue reference, the binding from lvalue was changed as well, which indicated that the rvalue reference was dependent on the lvalue.
1
2
3
4
    int a = 1, &&b = move(a);
    cout << a << " " << b << endl;
    b = 2;
    cout << a << " " << b << endl;

But when I bound some other rvalue reference that was converted from some random rvalue or lvalue to the rvalue reference, and then rebound an rvalue reference that was converted from an lvalue to the rvalue reference, then it showed that this time the rvalue reference and the lvalue were independent.
1
2
3
4
5
    int a = 1, &&b = move(int(2));
    b = move(a);
    cout << a << " " << b << endl;
    b = 2;
    cout << a << " " << b << endl;

And what surprised me more was that I could even bind an lvalue to "b".
1
2
3
4
5
    int a = 1, &&b = move(int(2));
    b = a;
    cout << a << " " << b << endl;
    b = 2;
    cout << a << " " << b << endl;

why?

These are all my questions, thanks!
Last edited on
Hi,

http://www.cplusplus.com/forum/beginner/156765/#msg804981


This is a reply that Cubbi posted a little earlier, it may be of help to you.

Cheers :+)
Hello hello, thanks for your reply. Actually no long after I started this thread, I realized that "b" could only be bound to some other object once and there was no such thing as it being rebound to another object. BUT I still cannot figure out why this code
 
int &&a = 1, &&b = move(a);

would work just fine, given that the compiler does not allow to bind an rvalue reference to another rvalue reference.
Hi,

I am probably out of my depth here, but is it because it is an xvalue expression?

cppreference wrote:
An xvalue is an expression that identifies an "eXpiring" object, that is, the object that may be moved from. The object identified by an xvalue expression may be a nameless temporary, it may be a named object in scope, or any other kind of object, but if used as a function argument, xvalue will always bind to the rvalue reference overload if available.

Only the following expressions are xvalues:

A function call or overloaded operator expression if the function's or the overloaded operator's return type is an rvalue reference to object type, such as std::move(val)

........

[other examples not shown]


If that's not it, then hopefully one of the experts here can answer.
> given that the compiler does not allow to bind an rvalue reference to another rvalue reference.

The compiler does not allow an rvalue reference to be bound to an lvalue.

A named rvalue reference is an lvalue. int&& a = 1 ; // (a) is an lvalue
An rvalue reference can't be bound to an lvalue. int&& b = a ; is an error

An unnamed rvalue reference is an rvalue.
1
2
3
int&& c = static_cast<int&&>(a) ; // fine
int&& d = std::move(a) ; // fine
int&& fn() ; int&& e = fn() ; // fine 

For the rationale, see: http://thbecker.net/articles/rvalue_references/section_05.html

> but is it because it is an xvalue expression?

Yes.
Last edited on
Get it. Thanks a lot!!!
Topic archived. No new replies allowed.