Как преобразовать 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 гарантирует, что это относится к типам объектов. Стандартная библиотека).

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

Другие вопросы по тегам