An object cannot be "rvalue" or "lvalue". The concept if different kind of values (lvalue, rvalue, xvalue, prvalue, etc.) are applicable to expressions, used to access object, not to objects themselves.
In your case functional cast expression Foo()
indeed produces a temporary object as an rvalue. However, inside any method of that temporary object you can use expression *this
, which will expose the very same temporary object as an lvalue. In other words, the popular belief that temporary objects are rvalues is patently incorrect. It is always a matter of what kind of expression you use to access the object.
There's nothing unusual in the fact that you can use it on the left-hand side of an assignment. The "lvalue" requirement applies to the built-in assignment operator only. For overloaded assignment operator there's no such requirement and there's never been one. And in your case you are using an overloaded operator.