Reputation: 10594
As per the C++ standard 12.8.7:
If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted;
and 12.8.18
If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted;
I am wondering why the move constructor/move assignment are not implicitly declared and defined as deleted (c++11 standard will not generate implicitly declared move constructor/move assignment in this case), if we only defined copy constructor or copy assignment operator?
Upvotes: 3
Views: 2082
Reputation: 254581
If the move constructor were deleted in that case, then trying to copy-initialise from an rvalue would be an error - the deleted move constructor would be a better match than the copy constructor.
Usually, you'd want copy-initialisation to copy, rather than be disallowed, if you haven't defined move semantics. To give that behaviour, the move constructor is simply not declared at all, so that copy-initialisation uses the copy constructor whether copying from an lvalue or an rvalue. (As long as the copy constructor takes its argument by const
reference.)
You can still delete the move operations yourself, if for some reason you want the rather odd quality of only being copyable from an lvalue.
Upvotes: 3
Reputation: 171167
If this was the case, then using an rvalue as the source of construction or assginment would result in a compilation error instead of falling back to a copy.
A function which does not exist (obviously) does not participate in overload resolution. A function which is defined as deleted does participate in overload resolution normally; if it's chosen, the compilation results in an error.
This code compiles:
struct Normal
{
Normal() {}
Normal(const Normal &) {}
};
int main()
{
Normal n(Normal{});
}
While this code results in an error:
struct Deleted
{
Deleted() {}
Deleted(const Deleted &) {}
Deleted(Deleted&&) = delete;
};
int main()
{
Deleted d(Deleted{});
}
Upvotes: 4