Почему конструктор перемещения должен использовать «ссылку на значение»?

Например, следующий конструктор перемещения работает без && (ссылка на значение):

Obj::Obj(Obj& obj) : elem { obj.elem }, data(obj.data) {

obj.elem = nullptr;
obj.data = 0;

}

Я не очень понимаю, зачем это нужно …

2

Решение

Аргументы ссылки Rvalue откажутся связывать с ссылками не-значения. Из-за этого ограничения move операции будут происходить только в том случае, если объект, из которого перемещается объект, никогда не может быть явно указан в коде позднее (потому что это временное удаление или возвращаемая локальная переменная) или потому, что вызывающий объект явно moveбуду от них.

Чтобы понять, почему это требуется, вы можете посмотреть историю auto_ptrили вы можете прочитать этот пример, который использует ваш Obj тип:

int main() {
Obj a;
Obj b = a; // oops!  You just *moved* a into b!
}

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

Более того, & ссылки отказываются связывать с временными — временный может связать только с const& или &&,

14

Другие решения

Ваш пример не может привязаться к временному, поэтому они не будут работать:

Obj makeObj() { return Obj(); }

Obj o1(Obj());     // Error
Obj o2(makeObj()); // Error

Кроме того, это очень легко ломает вещи, потому что у вас есть конструктор копирования, который крадет состояние у объекта, из которого он копирует:

Obj o1;
Obj o2{o1}; // o1 is modified
12

По вопросам рекламы [email protected]