Search code examples
c++c++11lvaluervalue

Need some help on r-value concept


When I try compiling following program, I get an error on l-value which makes sense. Error is: error C2106: '=' : left operand must be l-value

Code:

int main() 
{
    int a,b,c,d;
    b+c=d;
    return 0;
 }

But following code works absolutely fine when I replace integer with my own structure

struct MyStruct
{
    int val;
    MyStruct(){}
};

MyStruct operator+(MyStruct& s1, MyStruct& s2)
{
    MyStruct temp;
    return temp;
}

int main() 
{

    MyStruct a,b,c,d;
    b+c=d;
    return 0;
}

How come the second code compiles? I know I can return const from the operator+. But isn't b+c in second example a rvalue? So how come it compiles


Solution

  • Cory Klein has already explained here why the code compiles.

    I just want to add that if you want MyStruct to behave as the ints (and othe built-in types), then add this line to MyStruct:

    MyStruct& operator =(const MyStruct&) && = delete;
    

    This tells the compiler that that everytime the operator =() is called on a MyStruct object that is an rvalue (thanks to the ref-qualifier &&) the code should not be valid because the operator =() does not exist (= delete;). Indeed, GCC 4.8.1 emmits the following:

    error: use of deleted function 'MyStruct& MyStruct::operator=(const MyStruct&) &&'

    b+c=d;
       ^
    

    Update: Following the comment by Casey (many thanks).

    There's one issue with adding the line above to MyStruct. It also prevents assignment to an lvalue. That is, the line below also becomes illegal:

    b = c;
    

    If you want to disable assignment to an rvalue but still allows assignment to lvalues, then instead of the line above, add this one to MyStruct:

    MyStruct& operator =(const MyStruct&) & = default;
    

    (or provide a correct implementation if the compiler generated one doesn't fit your purposes.)