2016-09-02 11 views
17

Я пытался реализовать конструктор перемещения для класса без конструктора копирования. У меня возникла ошибка, когда конструктор по умолчанию для члена класса отсутствовал.Почему конструктор перемещения требует конструктора по умолчанию для своих членов?

Вот простой пример, чтобы проиллюстрировать это:

struct A { 
public: 
     A() = delete; 
     A(A const&) = delete; 
     A(A &&a) {} 
}; 

struct B { 
     A a; 
     B() = delete; 
     B(B const&) = delete; 
     B(B &&b) {} 
}; 

Попытка собрать это, я получаю:

move_without_default.cc: In constructor ‘B::B(B&&)’: 
move_without_default.cc:15:11: error: use of deleted function ‘A::A()’ 
    B(B &&b) {} 
     ^
move_without_default.cc:6:2: note: declared here 
    A() = delete; 
^

Почему это ошибка? Все вокруг?

+8

заменить '{}' на '= default;' – cpplearner

+0

Поскольку конструктор по умолчанию 'A' удален, но' B' его использует. – tkausl

+6

Пустой конструктор перемещения не будет автоматически пытаться выполнить перемещение по каждому элементу. Конструктор перемещения пытается установить по умолчанию 'a', а не move-construct. – user2357112

ответ

17

Используйте список инициализаторов конструктора для инициализации члена A. Как написано, конструктор перемещения использует, как компилятор, конструктор по умолчанию для A.

B(B&& b) : a(std::move(b.a)) {} 
9

Конструктор перемещения вообще не должен обеспечивать инициализацию по умолчанию. Ваш конструктор перемещения делает.

Конструктор перемещения по-прежнему является конструктором . И поэтому он должен инициализировать все подобъекты. Если вы не предоставите явную инициализацию, то он попытается инициализировать их по умолчанию. И если он не может этого сделать, вы получите сообщение об ошибке.

Итак, вы можете либо инициализировать их (возможно, переместившись с b), либо просто использовать = default с вашим конструктором перемещения и позволить компилятору выполнять свою работу.

23

Почему конструктор перемещения требует конструктора по умолчанию для своих членов?

Двигаться конструктор , что вы определили по умолчанию, создает элемент. Если вы по умолчанию строите какие-либо элементы, для этих членов требуется конструктор по умолчанию.

Конструктор (будь он регулярным, копирует или перемещает) по умолчанию инициализирует элементы, которые не указаны в списке инициализации члена, или не имеют инициализацию члена по умолчанию. B::a не входит в список инициализации элемента конструктора перемещения (он вообще не имеет списка инициализации) и не имеет инициализации члена по умолчанию.

Все вокруг?

Наиболее просто, используйте конструктор по умолчанию: перемещение

B(B&&) = default; 

Конструктор двигаться по умолчанию шаг-конструирует членов.