开发者

Implicitly-declared Move-Operations do not fallback to Copy?

开发者 https://www.devze.com 2023-04-05 08:52 出处:网络
Do I readN3291 \"12.8.(11/15/28) Copying and moving class objects class.copy]\" correct that the implicitly-declared move constructor

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 =deleted, because the non-static data-member data_ 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;
 };
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号