命名空间
变体
操作

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

来自 cppreference.cn
< cpp‎ | container‎ | map
 
 
 
 
std::pair<iterator, bool> insert( const value_type& value );
(1)
template< class P >
std::pair<iterator, bool> insert( P&& value );
(2) (since C++11)
std::pair<iterator, bool> insert( value_type&& value );
(3) (since C++17)
(4)
iterator insert( iterator pos, const value_type& value );
(until C++11)
iterator insert( const_iterator pos, const value_type& value );
(since C++11)
template< class P >
iterator insert( const_iterator pos, P&& value );
(5) (since C++11)
iterator insert( const_iterator pos, value_type&& value );
(6) (since C++17)
template< class InputIt >
void insert( InputIt first, InputIt last );
(7)
void insert( std::initializer_list<value_type> ilist );
(8) (since C++11)
insert_return_type insert( node_type&& nh );
(9) (since C++17)
iterator insert( const_iterator pos, node_type&& nh );
(10) (since 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 是一个空 节点句柄,则不执行任何操作并返回 end 迭代器。否则,如果容器尚未包含键等效于 nh.key() 的元素,则将 nh 拥有的元素插入到容器中,并返回指向键等效于 nh.key() 的元素的迭代器(无论插入成功还是失败)。如果插入成功,则 nh 被移动,否则它保留元素的所有权。元素被插入到尽可能靠近 pos 正前方的的位置。如果 nh 不为空且 get_allocator() != nh.get_allocator(),则行为未定义。

没有迭代器或引用失效。如果插入成功,则在节点句柄中持有时获得的元素的指针和引用将失效,并且在该元素被提取之前获得的该元素的指针和引用将变为有效。(since C++17)

目录

[编辑] 参数

pos - 迭代器,指向新元素将要插入的位置之前的位置
value - 要插入的元素值
first, last - 定义要插入的元素的范围的迭代器对
ilist - 要从中插入值的初始化列表
nh - 兼容的节点句柄
类型要求
-
InputIt 必须满足 LegacyInputIterator 的要求。

[编辑] 返回值

1-3) 一个 pair,包含指向插入元素的迭代器(或阻止插入的元素)和一个 bool 值,该值设置为 true 仅当插入发生时。
4-6) 指向插入元素的迭代器,或指向阻止插入的元素。
7,8) (无)
9) insert_return_type 的对象,其成员初始化如下
  • 如果 nh 为空,则 insertedfalsepositionend(),并且 node 为空。
  • 否则,如果插入发生,则 insertedtrueposition 指向插入的元素,并且 node 为空。
  • 如果插入失败,则 insertedfalsenode 具有 nh 的先前值,并且 position 指向键等效于 nh.key() 的元素。
10) 如果 nh 为空,则为 end 迭代器;如果插入发生,则为指向插入元素的迭代器;如果插入失败,则为指向键等效于 nh.key() 的元素的迭代器。

[编辑] 异常

1-6) 如果任何操作抛出异常,则插入不起作用。

[编辑] 复杂度

1-3) 对数时间复杂度,与容器的大小成对数关系,O(log(size()))
4-6) 如果插入发生在 after(直到 C++11)before(since 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 如果范围 [firstlast) 根据 Compare 排序,则重载 (7) 的复杂度必须为线性
在此特殊情况下,删除了线性要求
LWG 316 C++98 在重载 (1) 的返回值中,未指定哪个 bool 值指示成功插入
成功由 true 指示
LWG 2005 C++11 重载 (2,5) 的描述不佳 改进了描述

[编辑] 参见

(C++11)
就地构造元素
(public member function) [编辑]
使用提示就地构造元素
(public member function) [编辑]
如果键已存在,则插入元素或赋值给当前元素
(public member function) [编辑]
创建从参数推断类型的 std::insert_iterator
(function template) [编辑]