欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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


}
相关标签: c++