跳到主要内容

std::unordered_map 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) 相同。

    仅当 Hash::is_transparentKeyEqual::is_transparent 是有效且均表示一个类型,并且 iteratorconst_iterator 均不能从 K 隐式转换为时,此重载才参与重载解析。

    这假定这样的 Hash 可以与 KKey 类型一起调用,并且 KeyEqual 是透明的,这共同允许在不构造 Key 实例的情况下调用此函数。

在任何情况下,都不会复制或移动元素,只重新指向容器节点的内部指针。

失效

提取节点只会使指向被提取元素的迭代器失效,并保留未擦除元素的相对顺序。

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

参数

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

返回值

一个拥有被提取元素的 node handle,或者在 (2-3) 中未找到元素时为空的节点句柄。

复杂度

平均情况,常数 - O(1)
最坏情况下,与容器的大小呈线性关系 - O(size())

异常

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

备注

使用 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 <unordered_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::unordered_map<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)
本文源自此 CppReference 页面。为了改进或编辑偏好,内容可能已被修改。点击“编辑此页面”以查看对本文档的所有更改。
悬停查看原始许可证。

std::unordered_map 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) 相同。

    仅当 Hash::is_transparentKeyEqual::is_transparent 是有效且均表示一个类型,并且 iteratorconst_iterator 均不能从 K 隐式转换为时,此重载才参与重载解析。

    这假定这样的 Hash 可以与 KKey 类型一起调用,并且 KeyEqual 是透明的,这共同允许在不构造 Key 实例的情况下调用此函数。

在任何情况下,都不会复制或移动元素,只重新指向容器节点的内部指针。

失效

提取节点只会使指向被提取元素的迭代器失效,并保留未擦除元素的相对顺序。

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

参数

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

返回值

一个拥有被提取元素的 node handle,或者在 (2-3) 中未找到元素时为空的节点句柄。

复杂度

平均情况,常数 - O(1)
最坏情况下,与容器的大小呈线性关系 - O(size())

异常

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

备注

使用 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 <unordered_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::unordered_map<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)
本文源自此 CppReference 页面。为了改进或编辑偏好,内容可能已被修改。点击“编辑此页面”以查看对本文档的所有更改。
悬停查看原始许可证。