std::map<Key,T,Compare,Allocator>::insert
来自cppreference.com
std::pair<iterator,bool> insert( const value_type& value ); |
(1) | |
template< class P > std::pair<iterator,bool> insert( P&& value ); |
(2) | (C++11 起) |
std::pair<iterator,bool> insert( value_type&& value ); |
(3) | (C++17 起) |
(4) | ||
iterator insert( iterator hint, const value_type& value ); |
(C++11 前) | |
iterator insert( const_iterator hint, const value_type& value ); |
(C++11 起) | |
template< class P > iterator insert( const_iterator hint, P&& value ); |
(5) | (C++11 起) |
iterator insert( const_iterator hint, value_type&& value ); |
(6) | (C++17 起) |
template< class InputIt > void insert( InputIt first, InputIt last ); |
(7) | |
void insert( std::initializer_list<value_type> ilist ); |
(8) | (C++11 起) |
insert_return_type insert(node_type&& nh); |
(9) | (C++17 起) |
iterator insert(const_iterator hint, node_type&& nh); |
(10) | (C++17 起) |
若容器尚未含有带等价关键的元素,则插入元素到容器中。
1-3) 插入
value
。重载 (2) 等价于 emplace(std::forward<P>(value)) ,且仅若 std::is_constructible<value_type, P&&>::value == true 才参与重载决议。4-6) 插入
value
到尽可能接近,恰好前于(C++11 起) hint
的位置。重载 (4) 等价于 emplace_hint(hint, std::forward<P>(value)) ,且仅若 std::is_constructible<value_type, P&&>::value == true 才参与重载决议。9) 若
nh
是空的结点把柄,则不做任何事。否则插入 nh
所占有的元素到容器,若容器尚未含有拥有等价于 nh.key() 的关键的元素。若 nh
非空且 get_allocator() != nh.get_allocator() 则行为未定义。10) 若
nh
是空的结点把柄,则不做任何事并返回尾迭代器。否则,插入 nh
所占有的元素到容器,若容器尚未含有拥有等价于 nh.key() 的关键的元素,并返回指向拥有等于 nh.key() 的关键的元素的迭代器(无关乎插入成功还是失败)。若插入成功,则从 nh
移动,否则它保持该元素的所有权。元素被插入到尽可能接近正好先于 hint
的位置。若 nh
非空且 get_allocator() != nh.get_allocator() 则行为未定义。没有迭代器或引用被非法化。若插入成功,则在结点把柄保有元素时获得的指向该元素的指针和引用被非法化,而在提取前获得的指向元素的指针和引用变得合法。 (C++17 起)
参数
hint | - |
| ||||
value | - | 要插入的值 | ||||
first, last | - | 要插入的元素范围 | ||||
ilist | - | 插入值来源的 initializer_list | ||||
nh | - | 兼容的结点把柄 | ||||
类型要求 | ||||||
-InputIt 必须满足老式输入迭代器 (LegacyInputIterator) 的要求。
|
返回值
1-3) 返回由指向被插入元素的迭代器(或阻止插入的元素的迭代器)和指代插入是否发生的 bool 组成的 pair 。
4-6) 返回指向被插入元素的迭代器,或指向阻止插入的元素的迭代器。
7-8) (无)
9) 返回
insert_return_type
,其成员初始化如下:若 nh
为空,则 inserted
为 false
, position
为 end() ,而 node
为空。否则发生插入, inserted
为 true
, position
指向被插入元素,而 node
为空。若插入失败,则 inserted
为 false
, node
拥有 nh
的先前值,而 position
指向拥有等价于 nh.key() 的关键的元素。10) 若
nh
为空则为尾迭代器,若插入发生则为指向被插入元素的迭代器,而若插入失败则为指向拥有等价于 nh.key() 的关键的元素的迭代器。异常
1-6) 若任何操作抛出异常,则插入无效果(强异常保证)。
7-8) 若任何操作抛出异常,则程序在合法状态(基础异常保证)。
9-10) 若任何操作抛出异常,则插入无效果, nh 保持不变(强异常保证)。
复杂度
1-3) 与容器大小成对数,
O(log(size()))
。
4-6) 若插入恰好发生在 hint 后的位置则为均摊常数,否则与容器大小成对数。
|
(C++11 前) |
4-6) 若插入恰好发生在 hint 前的位置则为均摊常数,否则与容器大小成对数。
|
(C++11 起) |
7-8)
O(N*log(size() + N))
,其中 N 是要插入的元素数。9) 与容器大小成对数,
O(log(size()))
。10) 若插入恰好发生在 hint 前的位置则为均摊常数,否则与容器大小成对数。
注解
有提示插入 (4-6) 不返回 bool ,这是为了与顺序容器上的定位插入,如 std::vector::insert 签名兼容。这使得可以创建泛型插入器,例如 std::inserter 。检查有提示插入是否成功的一种方式是比较插入前后的 size() 。
示例
运行此代码
#include <iomanip> #include <iostream> #include <map> #include <string> using namespace std::literals; template<typename It> void printInsertionStatus(It it, bool success) { std::cout << "Insertion of " << it->first << (success ? " succeeded\n" : " failed\n"); } int main() { std::map<std::string, float> karasunoPlayerHeights; // 重载 3 :从右值引用插入 const auto [it_hinata, success] = karasunoPlayerHeights.insert({"Hinata"s, 162.8}); printInsertionStatus(it_hinata, success); { // 重载 1 :从左值引用插入 const auto [it, success2] = karasunoPlayerHeights.insert(*it_hinata); printInsertionStatus(it, success2); } { // 重载 2 :经由转发到 emplace 插入 const auto [it, success] = karasunoPlayerHeights.insert({"Kageyama", 180.6}); printInsertionStatus(it, success); } { // 重载 6 :带位置提示从右值引用插入 const std::size_t n = std::size(karasunoPlayerHeights); const auto it = karasunoPlayerHeights.insert(it_hinata, {"Azumane"s, 184.7}); printInsertionStatus(it, std::size(karasunoPlayerHeights) != n); } { // 重载 4 :带位置提示从左值引用插入 const std::size_t n = std::size(karasunoPlayerHeights); const auto it = karasunoPlayerHeights.insert(it_hinata, *it_hinata); printInsertionStatus(it, std::size(karasunoPlayerHeights) != n); } { // 重载 5 :带位置提示经由转发到 emplace 插入 const std::size_t n = std::size(karasunoPlayerHeights); const auto it = karasunoPlayerHeights.insert(it_hinata, {"Tsukishima", 188.3}); printInsertionStatus(it, std::size(karasunoPlayerHeights) != n); } auto node_hinata = karasunoPlayerHeights.extract(it_hinata); std::map<std::string, float> playerHeights; // 重载 7 :从范围插入 playerHeights.insert(std::begin(karasunoPlayerHeights), std::end(karasunoPlayerHeights)); // 重载 8 :从 initializer_list 插入 playerHeights.insert({{"Kozume"s, 169.2}, {"Kuroo", 187.7}}); // 重载 9 :插入结点 const auto status = playerHeights.insert(std::move(node_hinata)); printInsertionStatus(status.position, status.inserted); node_hinata = playerHeights.extract(status.position); { // 重载 10 :插入结点带位置提示 const std::size_t n = std::size(playerHeights); const auto it = playerHeights.insert(std::begin(playerHeights), std::move(node_hinata)); printInsertionStatus(it, std::size(playerHeights) != n); } // 打印结果 map std::cout << std::left << '\n'; for (const auto& [name, height] : playerHeights) std::cout << std::setw(10) << name << " | " << height << "cm\n"; }
输出:
Insertion of Hinata succeeded Insertion of Hinata failed Insertion of Kageyama succeeded Insertion of Azumane succeeded Insertion of Hinata failed Insertion of Tsukishima succeeded Insertion of Hinata succeeded Insertion of Hinata succeeded Azumane | 184.7cm Hinata | 162.8cm Kageyama | 180.6cm Kozume | 169.2cm Kuroo | 187.7cm Tsukishima | 188.3cm
参阅
(C++11) |
原位构造元素 (公开成员函数) |
(C++11) |
使用提示原位构造元素 (公开成员函数) |
(C++17) |
插入元素,或若键已存在则赋值给当前元素 (公开成员函数) |