Подтвердить что ты не робот

Перемещение с помощью вектора:: push_back

Предположим, что у меня есть следующий код:

#include <vector>
struct A {
    int a;
    int x;
};
int main() {
    using namespace std;
    A a1;
    A a2;
    vector<A> va;
    va.push_back(a1);
    va.push_back(move(a2));
}

Мне известно, что элементы std::vector хранятся смежно, в отличие от std:: list. В приведенном выше коде a2 перемещается, но не существует ли копирование a2 в вектор va? В чем разница между va.push_back(a2); и va.push_back(move(a2));?

4b9b3361

Ответ 1

В вашем случае нет эффективной разницы, поскольку вы используете конструкторы копирования, предоставленные компилятором. Вы увидите заметную разницу в производительности при использовании объектов, которые могут быть построены с возможностью перемещения, и приложите много усилий для копирования. В этом случае использование push_back(x) создаст копию объекта, а push_back(move(x)) сообщит push_back(), что он может "украсть" содержимое x, оставив x в неприменимом состоянии и undefined.

Учтите, если у вас есть вектор списков (std::vector<std::list<int> >), и вы хотите нажать список, содержащий 100 000 элементов. Без move() будет скопирована вся структура списка и все 100 000 элементов. С помощью move() некоторые указатели и другие мелкие биты данных перетасовываются, и это происходит. Это будет намного быстрее и потребует меньше общего объема памяти.

Ответ 2

При использовании va.push_back(a2) будет вызываться vector<T>::push_back(const T&), когда вы будете использовать va.push_back(move(a2)) версия vector<T>::push_back(T&&) будет вызываться...

Но в вашем случае нет разницы в производительности, поскольку

15 Неявно заданный конструктор копирования/перемещения для неединичного класса X выполняет частичную копию/перемещение своих оснований и членов.

Пункт 12.8 проект n3337.

Ответ 3

Я хочу отметить то, что другие ответы не прошли; заключается в том, что ?.push_back(move(?)) будет медленнее, чем ?.push_back(?) в вашем случае (когда у вас тривиально скопируемые объекты), потому что для перемещения конструктора необходимо установить нуль \set перемещенный объект, который эффективно вы пишете\копируете два объекта.