名稱空間
變體
操作

std::map<Key,T,Compare,Allocator>::insert

來自 cppreference.com
< cpp‎ | 容器‎ | map
 
 
 
 
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 時參與過載決議。
7) 插入範圍 [firstlast) 中的元素。如果範圍中有多個元素的鍵比較相等,則插入哪個元素是未指定的(待定 LWG2844)。
8) 插入初始化列表 ilist 中的元素。如果範圍中有多個元素的鍵比較相等,則插入哪個元素是未指定的(待定 LWG2844)。
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 為空,則 insertedfalsepositionend(),且 node 為空。
  • 否則,如果插入發生,則 insertedtrueposition 指向插入的元素,且 node 為空。
  • 如果插入失敗,則 insertedfalsenode 具有 nh 的前一個值,且 position 指向一個鍵與 nh.key() 等效的元素。
10) 如果 nh 為空,則為末尾迭代器;如果插入發生,則為指向已插入元素的迭代器;如果插入失敗,則為指向鍵與 nh.key() 等效的元素的迭代器。

[編輯] 異常

1-6) 如果任何操作丟擲異常,則插入無效。

[編輯] 複雜度

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) 的複雜度被要求為線性時間,如果
範圍 [firstlast) 根據 Compare 排序
在此特殊情況下
取消線性要求
LWG 316 C++98 在過載 (1) 的返回值中,未指定
哪個 bool 值表示成功插入
成功
true 表示
LWG 2005 C++11 過載 (2,5) 描述不佳 改進了描述

[編輯] 參見

(C++11)
就地構造元素
(公共成員函式) [編輯]
使用提示就地構造元素
(公共成員函式) [編輯]
插入元素或如果鍵已存在則賦值給當前元素
(公共成員函式) [編輯]
建立從引數推斷型別的std::insert_iterator
(函式模板) [編輯]