6

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?

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
towi
  • 21,587
  • 28
  • 106
  • 187
  • Do you mean that `copyOnly_` is the reason for `Question` being not movable instead of `data_` or do I miss something important? – pmr Oct 03 '11 at 18:13

1 Answers1

5

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;
 };
Alok Save
  • 202,538
  • 53
  • 430
  • 533
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212