当我们创建一个对象并将其分配给一个变量,然后将其添加到某个容器中时,假设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));
?
答案 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将创建一个临时文件,然后将其复制为额外副本)