命名空间
变体
操作

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

来自 cppreference.com
< cpp‎ | container‎ | 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) 插入 value 到尽可能接近于 pos 之前的位置。
重载 (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 - 要插入新元素之前的位置的迭代器
- 要插入的元素值
first,last - 要插入的元素范围
ilist - 要从中插入值的初始化列表
nh - 一个兼容的 节点句柄
类型要求
-
InputIt 必须满足 LegacyInputIterator 的要求。

[编辑] 返回值

1-3) 一个包含指向插入元素(或阻止插入的元素)的迭代器和 bool 值的 pair,当且仅当插入发生时,该值设置为 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) 如果插入发生在恰好 之后(直到 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) 的复杂度要求为线性,如果
范围 [firstlast) 是根据 Compare 排序的
删除了
此特殊情况下的线性要求
LWG 316 C++98 在重载 (1) 的返回值中,没有指定
哪个 bool 值指示插入成功
成功由
true 指示
LWG 2005 C++11 重载 (2,5) 描述不佳 改进了描述

[编辑] 另请参阅

(C++11)
原地构造元素
(公共成员函数) [编辑]
使用提示原地构造元素
(公共成员函数) [编辑]
插入元素或如果键已存在,则分配给当前元素
(公共成员函数) [编辑]
创建一个从参数推断的类型的 std::insert_iterator
(函数模板) [编辑]