Переместить конструктор на производный объект - PullRequest
44 голосов
/ 03 ноября 2010

Если у вас есть производный объект с конструктором перемещения и базовый объект также имеет семантику перемещения, как правильно вызвать конструктор перемещения базового объекта из конструктора перемещения производного объекта?

Сначала я попробовал самое очевидное:

 Derived(Derived&& rval) : Base(rval)
 { }

Однако, похоже, в конечном итоге вызывается конструктор копирования базового объекта . Затем я попытался явно использовать std::move здесь, вот так:

 Derived(Derived&& rval) : Base(std::move(rval))
 { }

Это сработало, но я запутался, зачем это нужно. Я думал, что std::move просто возвращает ссылку на значение. Но поскольку в этом примере rval уже является ссылкой на rvalue, вызов std::move должен быть излишним. Но если я не использую std::move здесь, он просто вызывает конструктор копирования. Так зачем звонить на std::move необходимо?

Ответы [ 2 ]

38 голосов
/ 03 ноября 2010

rval не является Rvalue. Это Lvalue внутри тела конструктора перемещения. Вот почему мы должны явно вызывать std::move.

См. это . Важное примечание

Обратите внимание, что аргумент x рассматривается как внутреннее значение переместить функции, даже если это объявлен в качестве ссылки параметр. Вот почему это необходимо сказать двигаться (х) вместо просто х, когда переходя к базовому классу. это является ключевым элементом безопасности движения семантика предназначена для предотвращения случайно двинулся дважды именованная переменная. Все ходы происходят только из значений или с явным приведением к значению, такому как использование std :: move. Если у вас есть имя для переменной, это является lvalue.

0 голосов
/ 01 февраля 2011

Вы действительно должны использовать std :: forward (obj), а не std :: move (obj). Forward возвращает правильное значение rvalue или lvalue в зависимости от значения obj, тогда как move превратит значение lvalue в значение r.

...