为什么 std::set 中的项目不能被"弹出"?



我知道std::set不允许非常量访问它的项目。我知道不可能将项目出集合 - 因为任何类型的非常量访问都可能破坏集合的顺序。

但是,我们可以从集合中删除项目。这不会破坏它,因为它只是迫使集合重组。那么,为什么我们不能"弹出"一个项目呢?为什么我不能同时取出物品并擦除它?

我问的原因是 - 我需要一个有序的unique_ptrs容器。有时我需要从一个容器中"弹出"unique_ptrs并将其转移到另一个容器中。它们必须被订购为我制作的自定义函子。

我不明白为什么不应该允许流行功能?

要从std::set中提取节点,您可以使用 C++17 中引入extract(...)成员函数:

#include <set>
#include <iostream>
int main()
{
std::set<int> set{1, 5, 3, 7, 2};
std::cout << "Original set: ";
for (auto e : set)
std::cout << e << ' ';
std::cout << 'n';
auto first = set.extract(set.begin());
std::cout << "Extracted value: " << first.value() << 'n';
std::cout << "New set: ";
for (auto e : set)
std::cout << e << ' ';
std::cout << 'n';
}

输出:

Original set: 1 2 3 5 7
Extracted value: 1
New set: 2 3 5 7

这是对pop()在C++中所做的事情的误解。例如,stack::pop()删除堆栈的顶部元素,但不返回它的副本。 这是因为返回类型的复制构造函数可能会引发异常,如果发生这种情况,该对象将已从堆栈中删除,因此无法恢复它。所以成语是用stack::top()获取对顶部元素的引用并复制它,然后使用stack::pop()将其删除。

对于一个集合也是如此:如果你将擦除一个元素和返回它的副本结合起来,你就有丢失它的风险。

最新更新