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,
foo
returns an lvalue, not an rvalue, so passing it tobar
is 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) takesthis
and returns something (which happens to be whatthis
points to) by lvalue reference. Now, how doesfoo
takethis
? 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: