emplace_backpush_back都是向容器内添加数据.

对于在容器中添加类的对象时, 相比于push_back,emplace_back可以避免额外类的复制和移动操作.

"emplace_back avoids the extra copy or move operation required when using push_back."


为了证实上述论断,我们自定义一个类,并在普通构造函数、拷贝构造函数、移动构造函数中打印相应描述:

#include <vector>
#include <string>
#include "time_interval.h"

class Foo {
public:
    Foo(std::string str) : name(str) {
        std::cout << "constructor" << std::endl;
    }
    Foo(const Foo& f) : name(f.name) {
        std::cout << "copy constructor" << std::endl;
    }
    Foo(Foo&& f) : name(std::move(f.name)){
        std::cout << "move constructor" << std::endl;
    }

private:
    std::string name;
};
int main() {


    std::vector<Foo> v;
    int count = 10000000;
    v.reserve(count);       //预分配十万大小,排除掉分配内存的时间

    {
        Foo temp("ceshi");
        v.push_back(temp);// push_back(const T&),参数是左值引用
        //打印结果:
        //constructor
        //copy constructor
    }

    v.clear();
    {
        Foo temp("ceshi");
        v.push_back(std::move(temp));// push_back(T &&), 参数是右值引用
        //打印结果:
        //constructor
        //move constructor
    }

    v.clear();
    {
        v.push_back(Foo("ceshi"));// push_back(T &&), 参数是右值引用
        //打印结果:
        //constructor
        //move constructor
    }

    v.clear();
    {
        std::string temp = "ceshi";
        TIME_INTERVAL_SCOPE("push_back(string):");
        v.push_back(temp);// push_back(T &&), 参数是右值引用
        //打印结果:
        //constructor
        //move constructor
    }

    v.clear();
    {
        std::string temp = "ceshi";
        v.emplace_back(temp);// 只有一次构造函数,不调用拷贝构造函数,速度最快
        //打印结果:
        //constructor
    }
}

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐