向向量添加元素时复制构造函数

时间:2019-02-07 22:48:24

标签: c++ move copy-constructor

当我们创建一个对象并将其分配给一个变量,然后将其添加到某个容器中时,假设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 :(得分:3)

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并没有真正的好处,因为move构造函数很便宜。

对于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).

答案 1 :(得分:2)

好吧,如果您不想在创建后使用它,则可以直接直接添加它(因为它将在适当的位置构造该对象)

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

(push_back将创建一个临时文件,然后将其复制为额外副本)