命名空间
变体
操作

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

来自 cppreference.cn
< 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
(函数模板) [编辑]