Namespaces
Variants

std::set<Key,Compare,Allocator>:: insert

From cppreference.net
std:: pair < iterator, bool > insert ( const value_type & value ) ;
(1) (自 C++26 起为 constexpr)
std:: pair < iterator, bool > insert ( value_type && value ) ;
(2) (自 C++11 起)
(自 C++26 起为 constexpr)
(3)
iterator insert ( iterator pos, const value_type & value ) ;
(C++11 前)
iterator insert ( const_iterator pos, const value_type & value ) ;
(自 C++11 起)
(自 C++26 起为 constexpr)
iterator insert ( const_iterator pos, value_type && value ) ;
(4) (自 C++11 起)
(自 C++26 起为 constexpr)
template < class InputIt >
void insert ( InputIt first, InputIt last ) ;
(5) (自 C++26 起为 constexpr)
void insert ( std:: initializer_list < value_type > ilist ) ;
(6) (自 C++11 起)
(自 C++26 起为 constexpr)
insert_return_type insert ( node_type && nh ) ;
(7) (自 C++17 起)
(自 C++26 起为 constexpr)
iterator insert ( const_iterator pos, node_type && nh ) ;
(8) (自 C++17 起)
(自 C++26 起为 constexpr)
template < class K >
std:: pair < iterator, bool > insert ( K && x ) ;
(9) (自 C++23 起)
(自 C++26 起为 constexpr)
template < class K >
iterator insert ( const_iterator pos, K && x ) ;
(10) (自 C++23 起)
(自 C++26 起为 constexpr)

尝试将元素插入到 * this 中。

  • 如果 * this 已包含具有等效键的元素,则不执行任何操作。
  • 否则,将元素插入到 * this 中。
1-4) 插入 value 。若提供 pos 参数,则 value 将尽可能插入到恰在 pos 之前的位置。
1,3) value_type 不可 复制插入 set 中,则行为未定义。
2,4) value_type 不可 移动插入 set 中,则行为未定义。
(C++11 起)
5) 插入来自范围 [ first , last ) 的元素。
若满足以下任意条件,则行为未定义:
(since C++11)
  • first last 是指向 * this 的迭代器。
6) 从初始化列表 ilist 插入元素。
等价于 insert ( ilist. begin ( ) , ilist. end ( ) )
7) nh 为空 节点句柄 ,则无操作。否则,若容器中尚未包含与 nh. key ( ) 等效的键,则将 nh 所拥有的元素插入容器。若 nh 非空且 get_allocator ( ) ! = nh. get_allocator ( ) ,则行为未定义。
8) nh 为空 节点句柄 ,则不执行任何操作并返回结束迭代器。否则,若容器中尚未包含与 nh. key ( ) 等价的键对应的元素,则将 nh 所拥有的元素插入容器,并返回指向具有等价于 nh. key ( ) 键的元素迭代器(无论插入成功与否)。若插入成功,则 nh 被移空;否则其保留元素的所有权。该元素会尽可能插入到紧邻 pos 之前的位置。若 nh 非空且 get_allocator ( ) ! = nh. get_allocator ( ) ,则行为未定义。
9,10) 构造一个类型为 value_type 的对象 u ,使用 std:: forward < K > ( x ) ,然后将 u 插入到 * this 中。在构造 u 之前,会使用 x 透明地确定等效键是否存在。
若满足以下任一条件,则行为未定义:
  • value_type 无法通过 std:: forward < K > ( x ) 置入构造到 set 中。
  • equal_range ( u ) == equal_range ( x ) false
9) 仅当 Compare 满足 透明函数对象 要求时,此重载才会参与重载决议。
10) u 将被插入到尽可能接近 pos 之前的位置。
此重载仅在满足以下所有条件时参与重载决议:

不会使任何迭代器或引用失效。 若插入成功,则通过节点句柄持有该元素期间获得的指针和引用将失效,而该元素被提取之前获得的指针和引用将变为有效。 (C++17 起)

目录

参数

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

返回值

1,2) 返回一个由迭代器和布尔值组成的对:迭代器指向被插入的元素(或阻止插入的元素),布尔值当且仅当插入成功时被设为 true
3,4) 指向被插入元素的迭代器,或指向阻止插入的元素的迭代器。
7) 返回一个 insert_return_type 类型的对象,其成员按以下方式初始化:
  • nh 为空,则 inserted false position end ( ) ,且 node 为空。
  • 若插入成功,则 inserted true position 指向被插入元素,且 node 为空。
  • 若插入失败,则 inserted false node 保留 nh 的先前值,且 position 指向与 nh. key ( ) 等价的元素。
8) nh 为空则为结束迭代器,若发生插入则指向被插入元素的迭代器,若插入失败则指向具有与 nh. key ( ) 等价键的元素。
9) 一个由指向被插入元素(或阻止插入的元素)的迭代器与 bool 值组成的键值对,该布尔值当且仅当插入成功时被设为 true
10) 指向被插入元素的迭代器,或指向阻止插入的元素的迭代器。

异常

如果在插入单个元素期间任何操作抛出异常,则该插入操作不产生任何效果。

复杂度

给定 N 作为 size ( )

1,2) log(N)
3,4) 若插入发生在 之后 (C++11 前) 之前 (C++11 起) pos 的位置,则摊分常量;否则为 log(N)
5,6) log(N+M) ,其中 M 表示要插入的元素数量。
7) log(N)
8) 若插入发生在 pos 之前的位置,则为均摊常数时间复杂度,否则为 log(N)
9) log(N)
10) 若插入发生在 pos 之前的位置,则为均摊常数时间复杂度;否则为 log(N)

注释

提示插入 ( ( 3,4 ) ( 8 ) ( 10 ) ) 不返回布尔值,这是为了与顺序容器(如 std::vector::insert )的位置插入操作保持签名兼容。这使得创建通用插入器(如 std::inserter )成为可能。检查提示插入是否成功的一种方法是比较插入前后的 size()

重载版本 ( 5,6 ) 通常实现为循环调用以 end() 作为提示位的重载版本 ( 3 ) ;这些重载针对追加有序序列(例如另一个 std::set )进行了优化,该有序序列的最小元素大于 * this 中的最后一个元素。

如果范围内多个元素的键比较等价,则未指定插入哪个元素(待解决 LWG2844 )。

功能测试 标准 功能特性
__cpp_lib_associative_heterogeneous_insertion 202311L (C++26) 有序 无序 关联容器中剩余的成员函数提供异构重载。 ( 9,10 )

示例

#include <cassert>
#include <iostream>
#include <set>
int main()
{
    std::set<int> set;
    auto result_1 = set.insert(3);
    assert(result_1.first != set.end()); // 这是一个有效的迭代器
    assert(*result_1.first == 3);
    if (result_1.second)
        std::cout << "insert done\n";
    auto result_2 = set.insert(3);
    assert(result_2.first == result_1.first); // 相同的迭代器
    assert(*result_2.first == 3);
    if (!result_2.second)
        std::cout << "no insertion\n";
}

输出:

insert done
no insertion

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 应用于 发布时行为 正确行为
LWG 233 C++98 pos 仅作为提示,可能被完全忽略 要求插入位置尽可能接近
pos 之前的位置
LWG 264 C++98 重载版本 ( 5 ) 在区间 [ first , last )
Compare 排序时需要线性复杂度
移除此特殊场景下的
线性复杂度要求
LWG 316 C++98 重载版本 ( 1 ) 的返回值中
未明确哪个 bool 值表示插入成功
成功由 true 表示

参见

(C++11)
原地构造元素
(公开成员函数)
使用提示原地构造元素
(公开成员函数)
创建从参数推断类型的 std::insert_iterator
(函数模板)