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

Copy constructor when adding an element to vector

当我们创建一个对象并将其分配给一个变量,然后我们想将它添加到某个容器时,比方说 std::vector,会发生两件事:

当我们不再需要该对象时,我们可以使用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));?

好吧,如果你创建后不打算使用它,你可以直接添加它(因为它会在适当的地方构建对象)

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

(push_back 将创建一个临时文件然后复制它以便额外复制)

std::make_shared<foo>(42) 已经是一个右值,不需要 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).