std::map<Key,T,Compare,Allocator>::insert
来自 cppreference.cn
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 pos, const value_type& value ); |
(C++11 前) | |
iterator insert( const_iterator pos, const value_type& value ); |
(C++11 起) | |
template< class P > iterator insert( const_iterator pos, P&& value ); |
(5) | (C++11 起) |
iterator insert( const_iterator pos, 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 pos, 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) 在尽可能接近 pos 之前的位置插入 value。
重载 (5) 等价于 emplace_hint(hint, std::forward<P>(value)) 且仅当 std::is_constructible<value_type, P&&>::value == true 时参与重载决议。
9) 如果 nh 是一个空的 节点句柄,则不执行任何操作。否则,如果容器中还没有一个键与 nh.key() 等效的元素,则将 nh 所拥有的元素插入到容器中。如果 nh 不为空且 get_allocator() != nh.get_allocator(),则行为未定义。
10) 如果 nh 是一个空的 节点句柄,则不执行任何操作并返回末尾迭代器。否则,如果容器中还没有一个键与 nh.key() 等效的元素,则将 nh 所拥有的元素插入到容器中,并返回指向键与 nh.key() 等效的元素的迭代器(无论插入成功与否)。如果插入成功,则 nh 被移动,否则它保留对元素的拥有权。该元素被插入到尽可能接近 pos 之前的位置。如果 nh 不为空且 get_allocator() != nh.get_allocator(),则行为未定义。
没有迭代器或引用失效。如果插入成功,则在节点句柄中持有时获取的元素的指针和引用会失效,而在提取之前获取的该元素的指针和引用会变为有效。(C++17 起)
目录 |
[编辑] 参数
pos | - | 指向新元素将插入位置之前的迭代器 |
value | - | 要插入的元素值 |
first, last | - | 定义要插入的元素范围的迭代器对 |
ilist | - | 要从中插入值的初始化列表 |
nh | - | 兼容的节点句柄 |
类型要求 | ||
-InputIt 必须满足 LegacyInputIterator 的要求。 |
[编辑] 返回值
1-3) 一个由指向已插入元素(或阻止插入的元素)的迭代器和布尔值组成的对,当且仅当插入发生时,布尔值设置为 true。
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-10 |
[编辑] 复杂度
1-3) 对容器大小呈对数,
O(log(size()))
。4-6) 如果插入发生在 pos 之后(直到 C++11)之前(C++11 起) 的位置,则分摊常数时间,否则对容器大小呈对数。
7,8)
O(N·log(size() + N))
,其中 N
是要插入的元素数量。9) 对容器大小呈对数,
O(log(size()))
。10) 如果插入发生在 pos 之前的位置,则分摊常数时间,否则对容器大小呈对数。
[编辑] 注意
带提示的插入 (4-6) 不返回布尔值,以与序列容器(如 std::vector::insert)上的位置插入具有签名兼容性。这使得创建泛型插入器(如 std::inserter)成为可能。检查带提示的插入是否成功的一种方法是比较插入前后的 size()
。
[编辑] 示例
运行此代码
#include <iomanip> #include <iostream> #include <map> #include <string> using namespace std::literals; template<typename It> void print_insertion_status(It it, bool success) { std::cout << "Insertion of " << it->first << (success ? " succeeded\n" : " failed\n"); } int main() { std::map<std::string, float> heights; // Overload 3: insert from rvalue reference const auto [it_hinata, success] = heights.insert({"Hinata"s, 162.8}); print_insertion_status(it_hinata, success); { // Overload 1: insert from lvalue reference const auto [it, success2] = heights.insert(*it_hinata); print_insertion_status(it, success2); } { // Overload 2: insert via forwarding to emplace const auto [it, success] = heights.insert(std::pair{"Kageyama", 180.6}); print_insertion_status(it, success); } { // Overload 6: insert from rvalue reference with positional hint const std::size_t n = std::size(heights); const auto it = heights.insert(it_hinata, {"Azumane"s, 184.7}); print_insertion_status(it, std::size(heights) != n); } { // Overload 4: insert from lvalue reference with positional hint const std::size_t n = std::size(heights); const auto it = heights.insert(it_hinata, *it_hinata); print_insertion_status(it, std::size(heights) != n); } { // Overload 5: insert via forwarding to emplace with positional hint const std::size_t n = std::size(heights); const auto it = heights.insert(it_hinata, std::pair{"Tsukishima", 188.3}); print_insertion_status(it, std::size(heights) != n); } auto node_hinata = heights.extract(it_hinata); std::map<std::string, float> heights2; // Overload 7: insert from iterator range heights2.insert(std::begin(heights), std::end(heights)); // Overload 8: insert from initializer_list heights2.insert({{"Kozume"s, 169.2}, {"Kuroo", 187.7}}); // Overload 9: insert node const auto status = heights2.insert(std::move(node_hinata)); print_insertion_status(status.position, status.inserted); node_hinata = heights2.extract(status.position); { // Overload 10: insert node with positional hint const std::size_t n = std::size(heights2); const auto it = heights2.insert(std::begin(heights2), std::move(node_hinata)); print_insertion_status(it, std::size(heights2) != n); } // Print resulting map std::cout << std::left << '\n'; for (const auto& [name, height] : heights2) 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++ 标准。
缺陷报告 | 应用于 | 发布时的行为 | 正确的行为 |
---|---|---|---|
LWG 233 | C++98 | pos 只是一个提示,它可能被完全忽略 | 插入要求 尽可能接近 pos 紧前位置 |
LWG 264 | C++98 | 重载 (7) 的复杂度被要求为线性时间,如果 范围 [ first, last) 根据 Compare 排序 |
在此特殊情况下 取消线性要求 |
LWG 316 | C++98 | 在重载 (1) 的返回值中,未指定 哪个 bool 值表示成功插入 |
成功 由 true 表示 |
LWG 2005 | C++11 | 重载 (2,5) 描述不佳 | 改进了描述 |
[编辑] 参见
(C++11) |
就地构造元素 (公共成员函数) |
(C++11) |
使用提示就地构造元素 (公共成员函数) |
(C++17) |
插入元素或如果键已存在则赋值给当前元素 (公共成员函数) |
创建从参数推断类型的std::insert_iterator (函数模板) |