map在c++11中增加了emplace操作,这个我虽然之前没用过,但是还是明白是什么意思,毕竟vector的emplace_back我还是用过的。但是map和vector不同的是,他有两个模板参数K和V。如果你的V有多个构造函数参数,那么emplace操作就有特殊的写法了。

上代码:

#include <iostream>
#include <map>
#include <utility>
using namespace std;
class A
{
    private:
    int m_value_a;
    int m_value_b;
    public:
    A(int value_a,int value_b):m_value_a(value_a),m_value_b(value_b)
    {cout<<"ctor"<<endl;}
    A(const A& o)
    {
        m_value_a = o.m_value_a;
        m_value_b = o.m_value_b;
        cout<<"copy ctor"<<endl;
    }
};

int main()
{
    map<int,A> m;
    cout<<"method 1"<<endl;
    m.insert({1,{2,3}});
    cout<<"method 2"<<endl;
    m.emplace(piecewise_construct,forward_as_tuple(1),make_tuple(2,3));
    return 0;
}

为了区分emplace的参数究竟是K的构造函数还是V的构造函数,所以要把各自的构造函数参数用tuple包起来。为了标识这种用法,让程序知道你不是传tuple作为参数,而只是用tuple来打包参数,所以要传一个piecewise_construct作为标记。这个类是定义在<utility>中的。

这段程序测试了insert和emplace两种插入方法的效率差异。

在debian系统,g++8.3.0 版本下编译运行,结果为

method 1
ctor
copy ctor
copy ctor
method 2
ctor

insert调用了一次构造函数,两次拷贝构造函数

而emplace只调用了一次构造函数

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注