98用太久,学习下11,根据网上资料的知识总结。
1. 区别
1.1 insert() 一次可以插入多个元素,而emplace() 每次只能插入一个元素。
1.2 当插入对象时,emplace()的效率更高。
因为emplace() 在插入元素时,是在容器的指定位置直接构造元素,而不是先单独生成,再将其复制(或移动)到容器中。因此,建议优先使用 emplace()。
2. 以std::vector为例
#include
class Test
{
public:
Test(int a) { cout << "Test(int)" << endl; }//构造函数
Test(const Test& a) { cout << "Test(const Test&)" << endl; }//拷贝构造函数
Test(const Test&& a) { cout << "Test(const Test&&)" << endl; }//移动构造函数
Test& operator = (const Test &a) { cout << "=(const Test&)" << endl; return *this; }
~Test() { cout << "~Test()" << endl; }
};
int main()
{
vector vecObj;
{
vecObj.reserve(10);//只开辟空间,没有构建对象
cout << "========insert================" << endl;
vecObj.insert(vecObj.end(), 100);
cout << "========push_back=============" << endl;
vecObj.push_back(200);
cout << "========emplace===============" << endl;
vecObj.emplace(vecObj.end(), 300);
cout << "========emplace_back==========" << endl;
vecObj.emplace_back(400);
cout << "=====================" << endl;
}
system("pause");
return 0;
}
运行结果:
由结果可以看出emplace()/emplace_back()只调用了一次构造函数,而insert()/push_back()多调用了一次移动构造函数(或拷贝构造函数)和析构函数。
注意:
a. 当拷贝构造函数和移动构造函数同时存在时,insert() 会优先调用移动构造函数。
b. vecObj.reserve(10); 预先开辟空间很重要,影响性能。
修改代码(注释掉移动构造函数和reserve调用):
#include
class Test
{
public:
Test(int a) { cout << "Test(int)" << endl; }//构造函数
Test(const Test& a) { cout << "Test(const Test&)" << endl; }//拷贝构造函数
//Test(const Test&& a) { cout << "Test(const Test&&)" << endl; }//移动构造函数
Test& operator = (const Test &a) { cout << "=(const Test&)" << endl; return *this; }
~Test() { cout << "~Test()" << endl; }
};
int main()
{
vector vecObj;
{
//vecObj.reserve(10);//只开辟空间,没有构建对象
cout << "========insert================" << endl;
vecObj.insert(vecObj.end(), 100);
cout << "========push_back=============" << endl;
vecObj.push_back(200);
cout << "========emplace===============" << endl;
vecObj.emplace(vecObj.end(), 300);
cout << "========emplace_back==========" << endl;
vecObj.emplace_back(400);
cout << "=====================" << endl;
}
system("pause");
return 0;
}
运行结果:
由结果可以看出如果没有调用reserve(),每次插入新元素时(改变vector大小),都会多次调用拷贝构造(或移动构造)函数和析构函数。调用次数由vector里原有元素个数决定,个数越多,越影响性能。
3. 以std::map为例
#include
运行结果:
由结果可以看出第二个insert方法多调用了一次移动构造函数(或拷贝构造函数)和析构函数。
3.1 map的emplace()的返回值为 pair 类型值,其包含一个迭代器和一个 bool 类型值。
添加新键值对成功时,返回的迭代器指向新添加的键值对,bool 值为 True;失败时,说明容器中本就包含一个键相等的键值对,此时返回的迭代器指向的就是容器中键相同的这个键值对,bool 值为 False。
3.2 map的emplace_hint()的返回值仅是一个迭代器,而不再是 pair 类型变量。
添加新键值对成功时,返回的迭代器指向新添加的键值对;反之,如果添加失败,该迭代器指向的是容器中和要添加键值对键相同的那个键值对。
另外,emplace_hint()方法需要传递一个迭代器作为第一个参数,该迭代器表明将新键值对添加到容器中的位置。需要注意的是,新键值对添加到容器中的位置,并不是此迭代器说了算,最终仍取决于该键值对的键的值。