std::multimap extract() 方法
- 自 C++23 起
- 自 C++17 起
// (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) Non const version only
node_type extract( const_iterator position );
// (2) Non const version only
node_type extract( const Key& k );
- (1) 解除与 position 指向的元素所在的节点的链接,并返回拥有该节点的节点句柄。
- (2) 如果容器中存在键与
k
等效的元素,则解除该元素所在节点与容器的链接,并返回拥有该节点的节点句柄。否则,返回一个空节点句柄。 - (3) 与 (2) 相同。只有当限定 ID
Compare::is_transparent
有效且表示一个类型,并且iterator
和const_iterator
都不能从K
隐式转换时,此重载才参与重载解析。它允许在不构造Key
实例的情况下调用此函数。
在这两种情况下,都不会复制或移动元素,只重新指向容器节点的内部指针(可能会发生重新平衡,如同 erase()
)。
失效
提取节点只会使指向被提取元素的迭代器失效。
重要
指向被提取元素的指针和引用仍然有效,但在元素被节点句柄拥有时不能使用:如果元素被插入到容器中,它们就可以使用了。
参数
position
- 指向此容器中有效迭代器k
- 用于标识要提取的节点的键x
- 任何类型的值,可以与标识要提取的节点的键进行透明比较
返回值
一个拥有提取元素的 node handle
,或者在未找到元素时为空 node handle
(重载 (2) 和 (3))。
异常
- (1) 不抛出任何异常。
- (2-3) 由
Compare
对象抛出的任何异常。
复杂度
- (1) 均摊常量 - O(1)。
- (2,3) 容器大小的对数级 O(log a.size())。
备注
使用 extract()
是唯一一种在不重新分配内存的情况下更改映射元素键的方法
std::map<int, std::string> m {{1, "mango"}, {2, "papaya"}, {3, "guava"}};
auto nh = m.extract(2);
nh.key() = 4;
m.insert(std::move(nh));
// m == {{1, "mango"}, {3, "guava"}, {4, "papaya"}}
特性测试宏:__cpp_lib_associative_heterogeneous_erasure
(用于重载 (3))。
示例
Main.cpp
#include <algorithm>
#include <iostream>
#include <string_view>
#include <map>
void print(std::string_view comment, const auto& data)
{
std::cout << comment;
for (auto [k, v] : data)
std::cout << ' ' << k << '(' << v << ')';
std::cout << '\n';
}
int main()
{
std::multimap<int, char> cont{{1, 'a'}, {2, 'b'}, {3, 'c'}};
print("Start:", cont);
// Extract node handle and change key
auto nh = cont.extract(1);
nh.key() = 4;
print("After extract and before insert:", cont);
// Insert node handle back
cont.insert(std::move(nh));
print("End:", cont);
}
输出
Start: 1(a) 2(b) 3(c)
After extract and before insert: 2(b) 3(c)
End: 2(b) 3(c) 4(a)