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
Cory Klein has already explained here why the code compiles.
I just want to add that if you want MyStruct
to behave as the int
s (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.)