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")