Namespaces
Variants

std::unordered_set<Key,Hash,KeyEqual,Allocator>:: insert

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

如果容器中尚未包含具有等效键的元素,则将元素插入容器。

1,2) 插入 value
3,4) 插入 value ,使用 hint 作为搜索起始位置的非强制性建议。
5) 插入范围 [ first , last ) 中的元素。如果范围内多个元素的键比较等价,则未指定具体插入哪个元素(待解决 LWG2844 )。
6) 从初始化列表 ilist 插入元素。如果范围内多个元素的键比较等价,则未指定具体插入哪个元素(待 LWG2844 解决)。
7) nh 为空 节点句柄 ,则无操作。否则,若容器中尚未包含与 nh. key ( ) 等效键的元素,则将 nh 所拥有的元素插入容器。若 nh 非空且 get_allocator ( ) ! = nh. get_allocator ( ) ,则行为未定义。
8) nh 是空的 节点句柄 ,则不执行任何操作并返回结束迭代器。否则,若容器中尚未包含与 nh. key ( ) 等价的键,则将 nh 所拥有的元素插入容器,并返回指向具有等价于 nh. key ( ) 键的元素的迭代器(无论插入成功与否)。若插入成功,则 nh 会被移走;否则其仍保留元素的所有权。 hint 作为搜索起始位置的非强制性建议。若 nh 非空且 get_allocator ( ) ! = nh. get_allocator ( ) ,则行为未定义。
9) * this 已包含与 obj 透明比较 等价 的元素,则不执行任何操作。否则,使用 std:: forward < K > ( obj ) 构造一个 value_type 类型的对象 u ,并将其插入 * this 。若 equal_range ( u ) ! = hash_function ( ) ( obj ) || contains ( u ) true ,则行为未定义。 value_type 必须能从 std:: forward < K > ( obj ) 可就位构造 unordered_set 中。此重载仅当 Hash KeyEqual 均为 透明 时参与重载决议。这要求 Hash 可同时被 K Key 类型调用,且 KeyEqual 为透明,共同使得无需构造 Key 实例即可调用此函数。
10) * this 已包含与 obj 透明比较 等价 的元素,则不执行任何操作。

否则,使用 std:: forward < K > ( obj ) 构造 value_type 类型的对象 u ,随后将 u 插入 * this Template:hint 作为搜索起始位置的非强制性建议。若 equal_range ( u ) ! = hash_function ( ) ( obj ) || contains ( u ) true ,则行为未定义。 value_type 必须满足从 std:: forward < K > ( obj ) unordered_set EmplaceConstructible 要求。此重载仅当满足以下条件时参与重载决议:

  • std:: is_convertible_v < K && , const_iterator > std:: is_convertible_v < K && , iterator > 均为 false ,且
  • Hash :: is_transparent KeyEqual :: is_transparent 合法且均表示类型(假定该 Hash 可同时被 K Key 类型调用,且 KeyEqual 具有透明性)
这些条件共同使得无需构造 Key 实例即可调用此函数。

如果在操作后新元素数量大于旧的 max_load_factor() * bucket_count() 将发生重哈希。
如果发生重哈希(由于插入操作),所有迭代器都会失效。否则(未发生重哈希),迭代器不会失效。 如果插入成功,当元素保存在节点句柄中时获取的指向该元素的指针和引用会失效,而在该元素被提取之前获取的指针和引用将变为有效。 (C++17 起)

目录

参数

hint - 迭代器,作为插入内容的建议位置
value - 要插入的元素值
first, last - 定义待插入元素源 范围 的迭代器对
ilist - 待插入值的初始化列表
nh - 兼容的 节点句柄
obj - 可与键进行透明比较的任意类型值
类型要求
-
InputIt 必须满足 LegacyInputIterator 的要求。

返回值

1,2) 返回一个由迭代器和布尔值组成的对:迭代器指向被插入的元素(或阻止插入的元素),布尔值当且仅当插入成功时被设为 true
3,4) 指向被插入元素的迭代器,或指向阻止插入的元素的迭代器。
5,6) (无)
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) 一个由迭代器和布尔值组成的对:迭代器指向被插入的元素(或阻止插入的元素),布尔值当且仅当插入成功时被设为 true
10) 指向被插入元素的迭代器,或指向阻止插入的元素的迭代器。

异常

1-4) 若任何操作抛出异常,则插入操作无效。

复杂度

1-4) 平均情况: O(1) ,最坏情况 O(size())
5,6) 平均情况: O(N) ,其中 N 为待插入元素的数量。最坏情况: O(N * size() + N)
7-10) 平均情况: O(1) ,最坏情况 O(size())

注释

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

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

示例

#include <array>
#include <iostream>
#include <unordered_set>
std::ostream& operator<<(std::ostream& os, std::unordered_set<int> const& s)
{
    for (os << '[' << s.size() << "] { "; int i : s)
        os << i << ' ';
    return os << "}\n";
}
int main ()
{
    std::unordered_set<int> nums{2, 3, 4};
    std::cout << "1) Initially: " << nums << std::boolalpha;
    auto p = nums.insert(1); // 插入元素,重载 (1)
    std::cout << "2) '1' was inserted: " << p.second << '\n';
    std::cout << "3) After insertion: " << nums;
    nums.insert(p.first, 0); // 使用提示插入,重载 (3)
    std::cout << "4) After insertion: " << nums;
    std::array<int, 4> a = {10, 11, 12, 13};
    nums.insert(a.begin(), a.end()); // 插入范围,重载 (5)
    std::cout << "5) After insertion: " << nums;
    nums.insert({20, 21, 22, 23}); // 插入初始化列表,重载 (6)
    std::cout << "6) After insertion: " << nums;
    std::unordered_set<int> other_nums = {42, 43};
    auto node = other_nums.extract(other_nums.find(42));
    nums.insert(std::move(node)); // 插入节点,重载 (7)
    std::cout << "7) After insertion: " << nums;
    node = other_nums.extract(other_nums.find(43));
    nums.insert(nums.begin(), std::move(node)); // 使用提示插入节点,重载 (8)
    std::cout << "8) After insertion: " << nums;
}

可能的输出:

1) Initially: [3] { 4 3 2 }
2) '1' was inserted: true
3) After insertion: [4] { 1 2 3 4 }
4) After insertion: [5] { 0 1 2 3 4 }
5) After insertion: [9] { 13 12 11 10 4 3 2 1 0 }
6) After insertion: [13] { 23 22 13 12 11 10 21 4 20 3 2 1 0 }
7) After insertion: [14] { 42 23 22 13 12 11 10 21 4 20 3 2 1 0 }
8) After insertion: [15] { 43 42 23 22 13 12 11 10 21 4 20 3 2 1 0 }

参见

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