Consider the following example struct
:
struct A {
int i;
void init(const A &a)
{
this->i = a.i;
}
A(int i)
{
this->i = i;
}
A(const A &a) = delete;
A &operator=(const A &a) = delete;
A(A &&a)
{
init(a); // Is this allowed?
}
A &operator=(A &&a)
{
init(a); // Is this allowed?
return *this;
}
};
The rvalue reference A &&a
is passed on to a function accepting a const A &a
, i.e. a constant lvalue reference. Is this allowed and resulting in well defined behaviour in C++?
Yes, it is allowed.
Note, that value category of the expression a
is lvalue, even though a
's declared type is rvalue reference.
Furthermore, if you create an rvalue from a
with std::move
, your code is still well-formed, as an rvalue can be bound to a const lvalue reference:
init(std::move(a)); // std::move(a) is an rvalue (to be precise, xvalue), but still OK