Например, следующий конструктор перемещения работает без &&
(ссылка на значение):
Obj::Obj(Obj& obj) : elem { obj.elem }, data(obj.data) {
obj.elem = nullptr;
obj.data = 0;
}
Я не очень понимаю, зачем это нужно …
Аргументы ссылки Rvalue откажутся связывать с ссылками не-значения. Из-за этого ограничения move
операции будут происходить только в том случае, если объект, из которого перемещается объект, никогда не может быть явно указан в коде позднее (потому что это временное удаление или возвращаемая локальная переменная) или потому, что вызывающий объект явно move
буду от них.
Чтобы понять, почему это требуется, вы можете посмотреть историю auto_ptr
или вы можете прочитать этот пример, который использует ваш Obj
тип:
int main() {
Obj a;
Obj b = a; // oops! You just *moved* a into b!
}
с надлежащим move
конструктор, он вызывается только тогда, когда правая часть является значением, которое будет немедленно отброшено способом, который компилятор может обнаружить, или вы вызываете move
,
Более того, &
ссылки отказываются связывать с временными — временный может связать только с const&
или &&
,
Ваш пример не может привязаться к временному, поэтому они не будут работать:
Obj makeObj() { return Obj(); }
Obj o1(Obj()); // Error
Obj o2(makeObj()); // Error
Кроме того, это очень легко ломает вещи, потому что у вас есть конструктор копирования, который крадет состояние у объекта, из которого он копирует:
Obj o1;
Obj o2{o1}; // o1 is modified