Implicitly-declared Move-Operations do not fallback to Copy?
Do I read N3291 "12.8.(11/15/28) Copying and moving class objects class.copy]" correct that the implicitly-declared move constructor
- does an element-wise move of all non-static data-members (probably via respectively defined
T(T&&)
- and if any non-static data-member can not be moved, the implicit move-constructor will be marked as deleted and not tried to be copied as a "fallback"? (yes, move is defined for built-in types, but actually is a copy).
开发者_开发百科and likewise the move-assign, using the respective T operator=(T&&)
of the elements.
Example:
struct CopyOnly {
CopyOnly();
CopyOnly(const CopyOnly&);
}; // declaring a copy means no implicit move.
struct Question {
std::vector<int> data_;
CopyOnly copyOnly_;
};
The class Question
- will have implicitly-declared copy-constructor and assign
- will have implicitly-declared move-constructor and move-assign, but they will be
=delete
d, because the non-static data-memberdata_
is only copyable, but not movable?
Update. A side-question: For Question q;
will std::move(q)
still work? Will the fallback to copy happen there? Or will the implicitly-declared move-ctor force the compiler to stop with an error? Here it does compile.
Update 2. What does the compiler generate for the non-movable data-members if I declare the move-ctor Question(Question&&) =default
? Does it then fallback to copying those?
You read it incorrectly. This would break lots of C++03 classes in cases such as the following
Question getQuestion();
Question q(getQuestion()); // use of deleted move constructor!
Instead, the FDIS says that a move constructor will be declared iff {there is no user declared {copy constructor, {copy, move} assignment operator, destructor} and the implicitly declared move constructor would not be defined as deleted}.
Regarding Update 2. It has been brought to my attention that if you explicitly-default the move constructor, it will be defined as deleted by the condition
for the move constructor, a non-static data member or direct or virtual base class with a type that does not have a move constructor and is not trivially copyable.
In the following, the move constructor will be defined as deleted, because CopyOnly
is not trivially copyable.
struct Question
{
std::vector<int> data_;
CopyOnly copyOnly_;
Question(Question&&) = default;
};
精彩评论