emplace_back 与 push_back的区别
程序员文章站
2022-03-21 16:27:07
...
1>: 问道emplace_back 与 push_back 的具体区别 基本上博客都会说 减少一次拷贝构造 或者 移动拷贝.
但具体 是怎末减少, 为什么 是拷贝构造 或者 移动构造 ?
emplace_back 允许显示转换. 如代码 //1> 中, 采用了显示转换 达到了 只调用 一次构造函数.
如果 emplace_back 传入的是 右值 它也和 push_back 一样, 调用两次, 和 //2> 中一样,
所以这就是 网上说的 减少 一次拷贝构造 或者 移动拷贝
为什么是拷贝构造或者 移动拷贝 (而不是 具体一种)
这个取决于 你传入的是左值 还是 右值. 左值就是拷贝构造, 右值 就是 移动拷贝
具体看 代码块 //3> 和代码块 //4>
2>: emplace_back 的使用条件
这要看你所写的类 支不支持 显示转换, 如果你的类是默认构造生成的, 那这个 就采用不了 emplace_back (), 因为你里面的入参放什么??? 总的有个参数, 让他帮你转换吧.
还有,当你的构造函数 有explicit 修饰, 使用emplace_back () 是可以显示转换.
3>: push_back 的最优使用
注意 代码块 //3> 和代码块 //4>
3 就 移动拷贝
4 就是 拷贝构造
这里的赋值都是 采用move 所以性能是一样的, 要是 4 采用的一般赋值, 性能就显现出来了.
所以在使用 push_back 的时候 最好传入的 右值,
左值也没关系, 可以通过使用 move() 转换成 右值.
#include <vector>
#include <string>
#include <iostream>
class Test
{
public:
std::string name;
explicit Test( const std::string &name):name(std::move(name))
{
std::cout << "I am being constructed.\n";
}
Test(const Test &other):name(std::move(other.name))
{
std::cout << "I am being copy constructed.\n";
}
Test( Test &&other):name(std::move(other.name))
{
std::cout << "I am being moved.\n";
}
};
int main()
{
//1>
std::cout<<"emplace_back:"<<std::endl;
std::vector<Test>T;
T.emplace_back("yang");
//输出 I am being constructed
//2>
std::cout<<"emplace_back2:"<<std::endl;
std::vector<Test>T4;
T4.emplace_back(Test("aaaa"));
//输出 I am being constructed
// I am being moved
//3>
std::cout<<"push_back1:"<<std::endl;
std::vector<Test>T2;
T2.push_back(Test("a"));
//输出 I am being constructed
// I am being moved
//4>
std::cout<<"push_back2:"<<std::endl;
std::vector<Test>T3;
Test t("aaa");
T3.push_back(t);
//输出 I am being constructed
// I am being copy constructed
}
上一篇: vector 删除指定元素