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) 在儘可能接近 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 (函式模板) |