class N {
public:
N() = default;
N(const N& n) { std::cout << "N copy\n"; };
private:
char c;
};
class H {
public:
H() = default;
H(H&) { std::cout << "H copy\n"; }
H(H&&) = default;
private:
N n;
};
int main() {
N n1, n2 = std::move(n1);
H h1, h2 = std::move(h1);
}
В VS2016 я определяю класс N, чтобы увидеть, что произойдет, если конструктор перемещения не будет определяться и не синтезироваться компилятором; и определите класс H, чтобы узнать, что произойдет, если удаленный конструктор перемещения по умолчанию будет удален.что-то запутанное о том, когда должен быть удален конструктор перемещения по умолчанию
В основной функции, выполняя первое заявление печатает «N копию», что означает, конструктор копирования называется, потому что нет никаких шагов конструктора в Н.
То, что я не могу понять, выполнив второе заявление «h2 = std :: move (h1)» также печатает «N copy».
Как я прочитал в C++ Primer (он основан на C++ 11), конструктор перемещения по умолчанию класса будет определен как удаленный, если класс имеет член, который определяет свой собственный конструктор копирования, но doesn ' t определить конструктор перемещения. Поскольку член n соответствует этому условию, конструктор перемещения H должен быть удален, «h2 = std :: move (h1)» должен вызывать конструктор копирования и, таким образом, печатать «H copy».
Однако напечатан только «N копия», что означает, что конструктор копирования H не вызывается, но вызывается конструктор копирования N. Зачем?
Вот что я думаю:
Компилятор все еще синтезируется конструктор перемещения для Н, и она работает так:
H(H&& h) :n(std::move(h.n)) {}
Здесь конструктор движение пытается переместить член п, и точно так же, как в «N n1, n2 = std :: move (n1);», вызывается конструктор копирования N, таким образом печатается «N копия».
Это объяснение имеет смысл, но согласно C++ Primer, перемещение по умолчанию конструктор ч должен быть определен как удаление. Это конструктор копирования H, который должен быть вызван.
Так что я смущен: это книга неправильно? Или это новое свойство, введенное новым стандартом? Или это вызвано компилятором?
Это [основная проблема 1402] (https://wg21.link/CWG1402). –
Спасибо, теперь я понимаю, что это какая-то модификация, внесенная C++ 14. – Dardai