Как преобразовать lvalue в rvalue? А что происходит с новым значением?
Я хотел бы переместить объект в std::vector
с помощью std::vector::push_back()
, Казалось бы, это возможно, так как есть std::vector::push_back(value_type&& val)
функция. Но из-за существования std::vector::push_back(value_type const & val)
, который копирует и будет переопределять вызов, мне нужно преобразовать объект lvalue в значение rvalue.
Как это сделать?
Пример:
struct X { int x; X(int x) : x(x) {} };
int main()
{
std::vector<X> ax;
X x(3);
ax.push_back(x); // <= Want to move x in to vector ax, not copy.
return 0;
}
На самом деле, может быть, это не может быть? Я спрашиваю об этом, потому что после написания этого примера мои новые вопросы:
- Если я перееду
x
вax
Какова стоимостьx.x
? ЕслиX
был явный деструктор, что будет сx
когда он покидает сферу?
1 ответ
Просто используйте std::move()
:
ax.push_back(std::move(x));
По поводу вашего вопроса:
Если я переместу х в топор, каково значение хх?
В этом случае ваш класс X
не содержит явно объявленного конструктора перемещения, поэтому компилятор сгенерирует тот, который выполняет перемещение по элементам X
участники. поскольку X
только один член типа int
и перемещая int
ничем не отличается от его копирования, то x.x
будет иметь то же значение, что и до перемещения из.
Если бы у X был явный деструктор, что бы произошло с x, когда он покидает область видимости?
Если X
имеет деструктор, объявленный пользователем, который будет препятствовать генерации неявного конструктора перемещения, но не генератора неявного копирования. Поэтому этот вызов функции:
ax.push_back(std::move(x));
Приведет к x
копируется в ax
, В любом случае, x
будет уничтожен при выходе из области видимости, поскольку имеет автоматическую продолжительность хранения - независимо от того, присутствует деструктор, объявленный пользователем, или нет.
В общем, не следует делать предположения о состоянии объекта, из которого было перемещено, за исключением того, что это состояние является действительным (параграф 17.6.5.15/1 Стандарта C++11 гарантирует, что это относится к типам объектов. Стандартная библиотека).
В частности, это означает, что единственными функциями, которые могут безопасно работать с перемещенным объектом, являются те, которые не имеют каких-либо предварительных условий для состояния этого объекта. Обычно двумя такими функциями являются деструктор и оператор присваивания (копирования или перемещения).