In C++ it is impossible to bind an r-value argument to a non-const l-value reference. But I noticed that when I call on the r-value object the method returning *this it compiles somehow.
Example: Obliviously this snippet od code will not compile
class X
{
};
void bar(X&)
{
}
int main()
{
foo(X{}); // invalid initialization of non-const reference of type 'X&' from an rvalue of type 'X'
}
But adding a simple method to X makes it compilable:
class X
{
public:
X& foo() { return *this; }
};
void bar(X&)
{
}
int main()
{
bar(X{}.foo());
}
Why does it work? Does it mean that after calling foo r-value object becomes l-value object? Is it safe to use such construction? Is there any other way to achieve similar effect without creating a new method (something like X.this)?
As mentioned in a comment,
fooreturns an lvalue, not an rvalue, so passing it tobaris just fine.If it feels strange that
X{}.foo()returns an lvalue even ifX{}itself is an rvalue, think offoo()as a function which (implicitly) takesthisand returns something (which happens to be whatthispoints to) by lvalue reference. Now, how doesfootakethis? Does it accept rvalue? Does it accept lvalues? Yes to both, but you could write things so as to allow only one usage (look for ref-qualified member functions here):However, pay attention to what you do: