Копировать конструктор при добавлении элемента в вектор - PullRequest
0 голосов
/ 08 февраля 2019

Когда мы создаем объект и присваиваем его переменной, а затем хотим добавить его в некоторый контейнер, скажем, std::vector, происходят две вещи:

  • , конструктор вызывается для созданияобъект ранее
  • конструктор копирования вызывается при выполнении push_back

Когда нам больше не нужен объект, мы можем использовать std::move, чтобы ускорить процесс,Допустим, у меня есть такой код:

#include <vector>
#include <cstdio>
#include <memory>

class foo
{
public:
    int x;
    foo() {}
    foo(int bar) : x(bar) {}
};

int main()
{
    std::vector<std::shared_ptr<foo>> foos;
    auto n = std::make_shared<foo>(42);
    foos.push_back(std::move(n));
}

Но что, если я не определил переменную?Что, если я только что сделал:

foos.push_back(std::make_shared<foo>(42));

Тогда вызывается конструктор копирования?Должен ли я использовать std::move?(как foos.push_back(std::move(std::make_shared<foo>(42)));) Я попытался проверить это в godbolt.org , но я не вижу ничего в беспорядке ассемблера.Итак, вызывается ли конструктор копирования (поэтому я бы использовал std::move, чтобы устранить это) или нет, и я должен оставить его так: foos.push_back(std::make_shared<foo>(42));?

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

std::make_shared<foo>(42) уже является значением r, нет необходимости в std::move.

Оба метода здесь похожи:

foos.push_back(std::make_shared<foo>(42));
foos.emplace_back(std::make_shared<foo>(42));

emplace_back позволяет построить на месте,так что вместо этого вы могли бы сделать

foos.emplace_back(new foo(42));

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

Для std::vector<foo> v; вы можете сравнить

foos.push_back(foo(42));    // call extra move constructor
foos.emplace_back(foo(42)); // call extra move constructor
foos.emplace_back(42);      // only call foo(int).
0 голосов
/ 08 февраля 2019

Ну, если вы не собираетесь использовать его после создания, вы можете напрямую добавить его напрямую (потому что он создаст объект на месте)

foos.emplace_back(std::make_shared<foo>(42));

(push_back создаст временный файл, а затем скопируйте его такдополнительная копия)

...