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 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) 插入 value 到尽可能接近于 pos 之前的位置。
重载 (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 | - | 要插入新元素之前的位置的迭代器 |
值 | - | 要插入的元素值 |
first,last | - | 要插入的元素范围 |
ilist | - | 要从中插入值的初始化列表 |
nh | - | 一个兼容的 节点句柄 |
类型要求 | ||
-InputIt 必须满足 LegacyInputIterator 的要求。 |
[编辑] 返回值
1-3) 一个包含指向插入元素(或阻止插入的元素)的迭代器和 bool 值的 pair,当且仅当插入发生时,该值设置为 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) 如果插入发生在恰好 之后(直到 C++11)之前(自 C++11 起) pos 的位置,则为均摊常数,否则为对容器大小的对数。
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++ 标准。
DR | 应用于 | 发布的行为 | 正确的行为 |
---|---|---|---|
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 (函数模板) |