This is a bug in Visual Studio for modern versions of C++, but it technically isn't a bug for the original release of C++11.
First, when I refer to Test
, I am talking about your first definition. So that we're clear.
By explicitly defaulting Test
's move constructor, you have caused the compiler to implicitly delete
the copy constructor and assignment operator, unless you explicitly specify otherwise. The thinking behind this rule is that, if you went out of your way to explicitly default
a constructor, you are probably trying to say something with that.
A type with only a defaulted move constructor looks like a move-only type, so the standard assumes that this is what you want. And if you don't want that, then you need to spell it out.
This doesn't happen for the copy constructor because move is considered a specialized form of copy. If a type is default copyable, it is logically default moveable, so leaving the move constructor implicitly defaulted makes sense.
Things like this are why you shouldn't default
a special member function unless you either know how that will affect the others or you intend to default/delete
/implement all of them.
In the initial release of C++11, the implicit deletion of copying for a defaulted move constructor would have made Test
non-TriviallyCopyable. However, the wording for Trivial Copyability was changed around C++14 via a defect report. The new wording allowed a type to be TriviallyCopyable even if some of the copy/move constructors/assignment operators are deleted. Thus making Test
TriviallyCopyable. Defect fixes usually apply retroactively, so technically a modern C++11 implementation should work too.
Visual Studio was never changed to fit the new wording. Hence the bug.