向向量添加元素时复制构造函数
Copy constructor when adding an element to vector
当我们创建一个对象并将其分配给一个变量,然后我们想将它添加到某个容器时,比方说 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));
?
好吧,如果你创建后不打算使用它,你可以直接添加它(因为它会在适当的地方构建对象)
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).
当我们创建一个对象并将其分配给一个变量,然后我们想将它添加到某个容器时,比方说 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));
?
好吧,如果你创建后不打算使用它,你可以直接添加它(因为它会在适当的地方构建对象)
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).