首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C++ std::set update很乏味:我不能就地更改元素

C++ std::set update很乏味:我不能就地更改元素
EN

Stack Overflow用户
提问于 2010-02-08 02:59:25
回答 5查看 27.7K关注 0票数 75

我发现std::set上的更新操作很乏味,因为cppreference上没有这样的API。所以我现在做的事情是这样的:

代码语言:javascript
复制
//find element in set by iterator
Element copy = *iterator;
... // update member value on copy, varies
Set.erase(iterator);
Set.insert(copy);

基本上,Set返回的迭代器是一个const_iterator,您不能直接更改它的值。

有没有更好的方法来做这件事?或者我应该通过创建自己的代码来覆盖std::set (我不知道它到底是如何工作的。)

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-02-08 03:04:38

set返回const_iterators (标准说明set<T>::iteratorconstset<T>::const_iteratorset<T>::iterator实际上可能是同一类型-请参阅n3000.pdf中的23.2.4/6 ),因为它是一个有序容器。如果它返回一个常规的iterator,你将被允许改变容器下的items值,这可能会改变排序。

您的解决方案是在set中更改项的惯用方法。

票数 78
EN

Stack Overflow用户

发布于 2018-09-22 21:54:06

在C++17中,使用extract()可以做得更好,这要归功于P0083

代码语言:javascript
复制
// remove element from the set, but without needing
// to copy it or deallocate it
auto node = Set.extract(iterator);
// make changes to the value in place
node.value() = 42;
// reinsert it into the set, but again without needing 
// to copy or allocate
Set.insert(std::move(node));

这将避免额外的类型副本和额外的分配/释放,并且也适用于仅移动类型。

您也可以按键执行extract。如果没有key,这将返回一个空节点:

代码语言:javascript
复制
auto node = Set.extract(key);
if (node) // alternatively, !node.empty()
{
    node.value() = 42;
    Set.insert(std::move(node));
}
票数 18
EN

Stack Overflow用户

发布于 2010-02-08 03:17:24

您可能希望改用std::map。使用影响键排序的Element部分,并将Element的所有内容作为值。将会有一些次要的数据重复,但您会有更容易(可能更快)的更新。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2217878

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档