跳到主要内容

std::multiset extract() 方法

// (1) Non const version only
node_type extract( const_iterator position );

// (2) Non const version only
node_type extract( const Key& k );

// (3) Non const version only
template< class K >
node_type extract( K&& x );
  • (1) 解除与 position 指向的元素所在的节点的链接,并返回拥有该节点的节点句柄。
  • (2) 如果容器中存在键与 k 等效的元素,则解除该元素所在节点与容器的链接,并返回拥有该节点的节点句柄。否则,返回一个空节点句柄。
  • (3)(2) 相同。此重载仅在 qualified-id Compare::is_transparent 有效且表示一个类型,并且 iteratorconst_iterator 都不能隐式转换为 K 时才参与重载决议。它允许在不构造 Key 实例的情况下调用此函数。

在任何一种情况下,都不会复制或移动元素,只重新指向容器节点的内部指针(可能会发生再平衡,与 erase() 类似)。

失效

提取节点只会使指向被提取元素的迭代器失效。

重要

指向被提取元素的指针和引用仍然有效,但在元素被节点句柄拥有时不能使用:如果元素被插入到容器中,它们就可以使用了。

参数

  • position - 指向此容器中有效迭代器
  • k - 用于标识要提取的节点的键
  • x - 任何类型的值,可以与标识要提取的节点的键进行透明比较

返回值

拥有被提取元素的节点句柄,如果未找到元素则为空节点句柄(重载(2)(3))。

异常

  • (1) 不抛出任何异常。
  • (2-3)Compare对象抛出的任何异常。

复杂度

  • (1) 均摊常量 - O(1)
  • (2-3) 容器大小的线性复杂度 - O(log size())

备注

使用 extract() 是在不重新分配内存的情况下更改 multiset 元素键的唯一方法

std::set<move_only_type> s;
s.emplace(...);
move_only_type mot = std::move(s.extract(s.begin()).value());

特性测试宏:__cpp_lib_associative_heterogeneous_erasure(用于重载 (3))。

示例

Main.cpp
#include <algorithm>
#include <iostream>
#include <string_view>
#include <set>

void print(std::string_view comment, const auto& data)
{
std::cout << comment;
for (auto datum : data)
std::cout << ' ' << datum;

std::cout << '\n';
}

int main()
{
std::multiset<int> cont{1, 2, 3};

print("Start:", cont);

// Extract node handle and change key
auto nh = cont.extract(1);
nh.value() = 4;

print("After extract and before insert:", cont);

// Insert node handle back
cont.insert(std::move(nh));

print("End:", cont);
}
输出
Start: 1 2 3
After extract and before insert: 2 3
End: 2 3 4
本文档源自 此 CppReference 页面。它可能为了改进或编辑偏好而有所修改。点击“编辑此页面”查看此文档的所有更改。
悬停查看原始许可证。

std::multiset extract() 方法

// (1) Non const version only
node_type extract( const_iterator position );

// (2) Non const version only
node_type extract( const Key& k );

// (3) Non const version only
template< class K >
node_type extract( K&& x );
  • (1) 解除与 position 指向的元素所在的节点的链接,并返回拥有该节点的节点句柄。
  • (2) 如果容器中存在键与 k 等效的元素,则解除该元素所在节点与容器的链接,并返回拥有该节点的节点句柄。否则,返回一个空节点句柄。
  • (3)(2) 相同。此重载仅在 qualified-id Compare::is_transparent 有效且表示一个类型,并且 iteratorconst_iterator 都不能隐式转换为 K 时才参与重载决议。它允许在不构造 Key 实例的情况下调用此函数。

在任何一种情况下,都不会复制或移动元素,只重新指向容器节点的内部指针(可能会发生再平衡,与 erase() 类似)。

失效

提取节点只会使指向被提取元素的迭代器失效。

重要

指向被提取元素的指针和引用仍然有效,但在元素被节点句柄拥有时不能使用:如果元素被插入到容器中,它们就可以使用了。

参数

  • position - 指向此容器中有效迭代器
  • k - 用于标识要提取的节点的键
  • x - 任何类型的值,可以与标识要提取的节点的键进行透明比较

返回值

拥有被提取元素的节点句柄,如果未找到元素则为空节点句柄(重载(2)(3))。

异常

  • (1) 不抛出任何异常。
  • (2-3)Compare对象抛出的任何异常。

复杂度

  • (1) 均摊常量 - O(1)
  • (2-3) 容器大小的线性复杂度 - O(log size())

备注

使用 extract() 是在不重新分配内存的情况下更改 multiset 元素键的唯一方法

std::set<move_only_type> s;
s.emplace(...);
move_only_type mot = std::move(s.extract(s.begin()).value());

特性测试宏:__cpp_lib_associative_heterogeneous_erasure(用于重载 (3))。

示例

Main.cpp
#include <algorithm>
#include <iostream>
#include <string_view>
#include <set>

void print(std::string_view comment, const auto& data)
{
std::cout << comment;
for (auto datum : data)
std::cout << ' ' << datum;

std::cout << '\n';
}

int main()
{
std::multiset<int> cont{1, 2, 3};

print("Start:", cont);

// Extract node handle and change key
auto nh = cont.extract(1);
nh.value() = 4;

print("After extract and before insert:", cont);

// Insert node handle back
cont.insert(std::move(nh));

print("End:", cont);
}
输出
Start: 1 2 3
After extract and before insert: 2 3
End: 2 3 4
本文档源自 此 CppReference 页面。它可能为了改进或编辑偏好而有所修改。点击“编辑此页面”查看此文档的所有更改。
悬停查看原始许可证。