Given the following toy code:
class X
{
public:
X() { }
X(const X&) { }
//X(X&&) = delete;
};
int main()
{
X x;
X y = std::move(x);
}
I know that X::X(X&&)
is implicitly deleted in this case because X(const X&)
exists as an user-declared constructor. But I'm a little bit confused with the meaning of the terminology "implicitly deleted" here: if we uncomment X(X&&) = delete;
, the code will behave differently, which means there is a difference between implicitly deleted and "explicitly" deleted.
There are two different understandings in my mind:
"implicitly deleted" means that the compiler generates some code similar to
X(X&&) = delete;
(that is, the compiler knows that there isX(X&&)
and it knows thatX(X&&)
is deleted), but the code generated differs fromX(X&&) = delete;
in a way such that whenX y = std::move(x);
tries to callX::X(X&&)
, the compiler selectX(const X&)
rather than reporting an error. (HadX(X&&) = delete;
been uncommented, the compiler will not selectX(const X&)
and will report an error)"implicitly deleted" means that
X(X&&)
is not declared in the class at all, in other words, the compiler does not have any information aboutX(X&&)
and thusX y = std::move(x);
is matched directly toX(const X&)
.
May I ask which of my understandings is the correct one?
My guess is that the former should be the correct one. Because if we change the above code as follows:
class X
{
public:
X() { }
//X(const X&) { }
X(X&&) {}
};
int main()
{
X x;
X y = x;
}
We get an error saying 'X::X(const X &)': attempting to reference a deleted function
which means the compiler knows the existence of X(const X &)
when it is implicitly deleted.
However, for me, my latter understanding seems to be a more straightforward way of getting the work done. So I wonder why we want to design the concept of "implicitly deleted" (it also gives me a little feeling of inconsistency since "implicitly deleted" needs to act differently from "explicitly deleted")