C++ STL set中的emplace和emplace_hint函数如何实现高效插入元素而不复制构造?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1233个文字,预计阅读时间需要5分钟。
要向`set`容器中添加新元素,`set`类模板提供了以下三个成员方法:
1. `insert(const value_type& v);` - 向`set`中插入一个元素`v`。如果元素已存在,则不添加。
2.`emplace(value_type&& v);` - 使用移动语义直接在容器内部构造元素`v`,从而可能更高效。
3.`emplace_hint(knd, value_type&& v);` - 类似于`emplace`,但允许指定插入位置。
请注意,这些方法的使用已在之前的章节中详细说明。
要知道,set 类模板提供的所有成员方法中,能实现向指定 set 容器中添加新元素的,只有 3 个成员方法,分别为 insert()、emplace() 和 emplace_hint()。其中 insert() 成员方法的用法已在前面章节做了详细的讲解,本节重点介绍剩下的这 2 个成员方法。emplace() 和 emplace_hint() 是 C++ 11 标准加入到 set 类模板中的,相比具有同样功能的 insert() 方法,完成同样的任务,emplace() 和 emplace_hint() 的效率会更高。
emplace() 方法的语法格式如下:
template <class... Args>
pair<iterator,bool> emplace (Args&&... args);
另外,该方法的返回值类型为 pair 类型,其包含 2 个元素,一个迭代器和一个 bool 值:
- 当该方法将目标元素成功添加到 set 容器中时,其返回的迭代器指向新插入的元素,同时 bool 值为 true;
- 当添加失败时,则表明原 set 容器中已存在相同值的元素,此时返回的迭代器指向容器中具有相同键的这个元素,同时 bool 值为 false。
下面程序演示 emplace() 方法的具体用法:
#include <iostream> #include <set> #include <string> using namespace std; int main() { //创建并初始化 set 容器 std::set<string>myset; //向 myset 容器中添加元素 pair<set<string, string>::iterator, bool> ret = myset.emplace("c.biancheng.net/stl/"); cout << "myset size = " << myset.size() << endl; cout << "ret.iter = <" << *(ret.first) << ", " << ret.second << ">" << endl; return 0; } 程序执行结果为:
myset size = 1
ret.iter = <c.biancheng.net/stl/, 1>
emplace_hint() 方法的功能和 emplace() 类似,其语法格式如下:
template <class... Args>
iterator emplace_hint (const_iterator position, Args&&... args);
- 该方法需要额外传入一个迭代器,用来指明新元素添加到 set 容器的具体位置(新元素会添加到该迭代器指向元素的前面);
- 返回值是一个迭代器,而不再是 pair 对象。当成功添加元素时,返回的迭代器指向新添加的元素;反之,如果添加失败,则迭代器就指向 set 容器和要添加元素的值相同的元素。
下面程序演示 emplace_hint() 方法的用法:
#include <iostream> #include <set> #include <string> using namespace std; int main() { //创建并初始化 set 容器 std::set<string>myset; //在 set 容器的指定位置添加键值对 set<string>::iterator iter = myset.emplace_hint(myset.begin(), "c.biancheng.net/stl/"); cout << "myset size = " << myset.size() << endl; cout << *iter << endl; return 0; } 程序执行结果为:
myset size = 1
c.biancheng.net/stl/
以上内容讲解了 emplace() 和 emplace_hint() 的用法,至于比 insert() 执行效率高的原因,可参照 map 容器 emplace() 和 emplace_hint() 比 insert() 效率高的原因,它们是完全一样的,这里不再赘述。
本文共计1233个文字,预计阅读时间需要5分钟。
要向`set`容器中添加新元素,`set`类模板提供了以下三个成员方法:
1. `insert(const value_type& v);` - 向`set`中插入一个元素`v`。如果元素已存在,则不添加。
2.`emplace(value_type&& v);` - 使用移动语义直接在容器内部构造元素`v`,从而可能更高效。
3.`emplace_hint(knd, value_type&& v);` - 类似于`emplace`,但允许指定插入位置。
请注意,这些方法的使用已在之前的章节中详细说明。
要知道,set 类模板提供的所有成员方法中,能实现向指定 set 容器中添加新元素的,只有 3 个成员方法,分别为 insert()、emplace() 和 emplace_hint()。其中 insert() 成员方法的用法已在前面章节做了详细的讲解,本节重点介绍剩下的这 2 个成员方法。emplace() 和 emplace_hint() 是 C++ 11 标准加入到 set 类模板中的,相比具有同样功能的 insert() 方法,完成同样的任务,emplace() 和 emplace_hint() 的效率会更高。
emplace() 方法的语法格式如下:
template <class... Args>
pair<iterator,bool> emplace (Args&&... args);
另外,该方法的返回值类型为 pair 类型,其包含 2 个元素,一个迭代器和一个 bool 值:
- 当该方法将目标元素成功添加到 set 容器中时,其返回的迭代器指向新插入的元素,同时 bool 值为 true;
- 当添加失败时,则表明原 set 容器中已存在相同值的元素,此时返回的迭代器指向容器中具有相同键的这个元素,同时 bool 值为 false。
下面程序演示 emplace() 方法的具体用法:
#include <iostream> #include <set> #include <string> using namespace std; int main() { //创建并初始化 set 容器 std::set<string>myset; //向 myset 容器中添加元素 pair<set<string, string>::iterator, bool> ret = myset.emplace("c.biancheng.net/stl/"); cout << "myset size = " << myset.size() << endl; cout << "ret.iter = <" << *(ret.first) << ", " << ret.second << ">" << endl; return 0; } 程序执行结果为:
myset size = 1
ret.iter = <c.biancheng.net/stl/, 1>
emplace_hint() 方法的功能和 emplace() 类似,其语法格式如下:
template <class... Args>
iterator emplace_hint (const_iterator position, Args&&... args);
- 该方法需要额外传入一个迭代器,用来指明新元素添加到 set 容器的具体位置(新元素会添加到该迭代器指向元素的前面);
- 返回值是一个迭代器,而不再是 pair 对象。当成功添加元素时,返回的迭代器指向新添加的元素;反之,如果添加失败,则迭代器就指向 set 容器和要添加元素的值相同的元素。
下面程序演示 emplace_hint() 方法的用法:
#include <iostream> #include <set> #include <string> using namespace std; int main() { //创建并初始化 set 容器 std::set<string>myset; //在 set 容器的指定位置添加键值对 set<string>::iterator iter = myset.emplace_hint(myset.begin(), "c.biancheng.net/stl/"); cout << "myset size = " << myset.size() << endl; cout << *iter << endl; return 0; } 程序执行结果为:
myset size = 1
c.biancheng.net/stl/
以上内容讲解了 emplace() 和 emplace_hint() 的用法,至于比 insert() 执行效率高的原因,可参照 map 容器 emplace() 和 emplace_hint() 比 insert() 效率高的原因,它们是完全一样的,这里不再赘述。

