跳到主要内容

std::map emplace_hint() 方法

// Non const version only
template <class... Args>
iterator emplace_hint( const_iterator hint, Args&&... args );

在尽可能靠近 hint 之前的位置插入一个新元素到容器中。该元素原地构造,即不执行复制或移动操作。

新元素(即 std::pair<const Key, T>)的构造函数使用与提供给 emplace 的完全相同的参数调用,通过 std::forward<Args>(args)... 进行转发。

不使任何迭代器或引用失效。

参数

  • hint - 指向新元素将插入位置之前的迭代器
  • args - 转发给元素构造函数的参数

返回值

返回指向新插入元素的迭代器。如果插入失败,因为元素已经存在,则返回指向具有等效键的已存在元素的迭代器。

复杂度

通常情况下,时间复杂度与容器大小呈对数关系 - O(log size())
如果新元素恰好插入到 hint 之前,则分摊常量时间 - O(1)

异常

如果任何操作抛出异常,此函数不产生任何影响(强异常保证)。

示例

Main.cpp
#include <chrono>
#include <iostream>
#include <iomanip>
#include <functional>
#include <map>

const int nof_operations = 100500;

int map_emplace() {
std::map<int, char> map;
for(int i = 0; i < nof_operations; ++i) {
map.emplace(i, 'a');
}
return map.size();
}

int map_emplace_hint() {
std::map<int, char> map;
auto it = map.begin();
for(int i = 0; i < nof_operations; ++i) {
map.emplace_hint(it, i, 'b');
it = map.end();
}
return map.size();
}

int map_emplace_hint_wrong() {
std::map<int, char> map;
auto it = map.begin();
for(int i = nof_operations; i > 0; --i) {
map.emplace_hint(it, i, 'c');
it = map.end();
}
return map.size();
}

int map_emplace_hint_corrected() {
std::map<int, char> map;
auto it = map.begin();
for(int i = nof_operations; i > 0; --i) {
map.emplace_hint(it, i, 'd');
it = map.begin();
}
return map.size();
}

int map_emplace_hint_closest() {
std::map<int, char> map;
auto it = map.begin();
for(int i = 0; i < nof_operations; ++i) {
it = map.emplace_hint(it, i, 'e');
}
return map.size();
}

void timeit(std::function<int()> map_test, std::string what = "") {
auto start = std::chrono::system_clock::now();
int mapsize = map_test();
auto stop = std::chrono::system_clock::now();
std::chrono::duration<double, std::milli> time = stop - start;
if (what.size() > 0 && mapsize > 0) {
std::cout << std::fixed << std::setprecision(2) << std::setw(5)
<< time.count() << " ms for " << what << '\n';
}
}

int main() {
timeit(map_emplace); // stack warmup
timeit(map_emplace, "plain emplace");
timeit(map_emplace_hint, "emplace with correct hint");
timeit(map_emplace_hint_wrong, "emplace with wrong hint");
timeit(map_emplace_hint_corrected, "corrected emplace");
timeit(map_emplace_hint_closest, "emplace using returned iterator");
}
输出
22.64  ms for plain emplace
8.81 ms for emplace with correct hint
22.27 ms for emplace with wrong hint
7.76 ms for corrected emplace
8.30 ms for emplace using returned iterator
本文源自此 CppReference 页面。它可能为了改进或编辑者的偏好而进行了修改。点击“编辑此页面”可查看对本文档进行的所有更改。
悬停查看原始许可证。

std::map emplace_hint() 方法

// Non const version only
template <class... Args>
iterator emplace_hint( const_iterator hint, Args&&... args );

在尽可能靠近 hint 之前的位置插入一个新元素到容器中。该元素原地构造,即不执行复制或移动操作。

新元素(即 std::pair<const Key, T>)的构造函数使用与提供给 emplace 的完全相同的参数调用,通过 std::forward<Args>(args)... 进行转发。

不使任何迭代器或引用失效。

参数

  • hint - 指向新元素将插入位置之前的迭代器
  • args - 转发给元素构造函数的参数

返回值

返回指向新插入元素的迭代器。如果插入失败,因为元素已经存在,则返回指向具有等效键的已存在元素的迭代器。

复杂度

通常情况下,时间复杂度与容器大小呈对数关系 - O(log size())
如果新元素恰好插入到 hint 之前,则分摊常量时间 - O(1)

异常

如果任何操作抛出异常,此函数不产生任何影响(强异常保证)。

示例

Main.cpp
#include <chrono>
#include <iostream>
#include <iomanip>
#include <functional>
#include <map>

const int nof_operations = 100500;

int map_emplace() {
std::map<int, char> map;
for(int i = 0; i < nof_operations; ++i) {
map.emplace(i, 'a');
}
return map.size();
}

int map_emplace_hint() {
std::map<int, char> map;
auto it = map.begin();
for(int i = 0; i < nof_operations; ++i) {
map.emplace_hint(it, i, 'b');
it = map.end();
}
return map.size();
}

int map_emplace_hint_wrong() {
std::map<int, char> map;
auto it = map.begin();
for(int i = nof_operations; i > 0; --i) {
map.emplace_hint(it, i, 'c');
it = map.end();
}
return map.size();
}

int map_emplace_hint_corrected() {
std::map<int, char> map;
auto it = map.begin();
for(int i = nof_operations; i > 0; --i) {
map.emplace_hint(it, i, 'd');
it = map.begin();
}
return map.size();
}

int map_emplace_hint_closest() {
std::map<int, char> map;
auto it = map.begin();
for(int i = 0; i < nof_operations; ++i) {
it = map.emplace_hint(it, i, 'e');
}
return map.size();
}

void timeit(std::function<int()> map_test, std::string what = "") {
auto start = std::chrono::system_clock::now();
int mapsize = map_test();
auto stop = std::chrono::system_clock::now();
std::chrono::duration<double, std::milli> time = stop - start;
if (what.size() > 0 && mapsize > 0) {
std::cout << std::fixed << std::setprecision(2) << std::setw(5)
<< time.count() << " ms for " << what << '\n';
}
}

int main() {
timeit(map_emplace); // stack warmup
timeit(map_emplace, "plain emplace");
timeit(map_emplace_hint, "emplace with correct hint");
timeit(map_emplace_hint_wrong, "emplace with wrong hint");
timeit(map_emplace_hint_corrected, "corrected emplace");
timeit(map_emplace_hint_closest, "emplace using returned iterator");
}
输出
22.64  ms for plain emplace
8.81 ms for emplace with correct hint
22.27 ms for emplace with wrong hint
7.76 ms for corrected emplace
8.30 ms for emplace using returned iterator
本文源自此 CppReference 页面。它可能为了改进或编辑者的偏好而进行了修改。点击“编辑此页面”可查看对本文档进行的所有更改。
悬停查看原始许可证。