如果您在c++中更新一个集合的成员,该集合会自动更改顺序吗
in case you update a member of a set in c++, does the set automatically change the order?
我想使用类型为node
的集合S
,我想操作集合中的成本部分,并按cost
:对集合进行排序
struct node
{
int label;
long cost=LONG_MAX;
bool visited=false;
bool operator < (const node &other) const { return cost < other.cost; }
}
set<node> S;
//here i just want to update the cost of a node in my set S
set<node>::iterator it=S.find(vertex);
*it.cost=200;
这会自动改变布景的顺序吗?
这会自动更改集合中的顺序吗?
它不仅不会更改set
的顺序,而且操作本身也是非法的。关联容器迭代器为键提供了const
类型,因此示例中的*it
具有node const
类型。
仔细想想,这是确保容器提供不变量的唯一方法。毕竟,it->cost = 200
怎么可能更新底层的set
呢?也许如果C++有反射,迭代器去引用到某个重载了operator=
的代理,那么。。。是的,听起来一团糟。
当前"更新"set
中元素的惯用方法包括擦除、修改,然后重新插入
auto it = S.find(vertex);
node cur = std::move(*it);
auto next = S.erase(it);
cur.cost = 200;
S.insert(next, cur);
无可否认,这相当乏味。
有一项建议(P0083R2)将在未来对此进行改进。
C++17的更新:该提议已被接受。现在您想要使用extract()
:
auto node = S.extract(vertex);
node.value().cost = 200;
S.insert(std::move(node));
这将避免您类型的额外副本和额外的分配/解除分配。
通常不能更改集合的现有内容。这是一个肮脏的小秘密,但std::set
迭代器实际上是const_iterator
s。继续编译它,你会得到编译错误。
当然,有一些方法可以解决这个问题,但它们会导致未定义的行为。
相关文章:
- 如何将结构插入到集合中并打印集合的成员
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 成员函数不能为集合迭代器和const_iterator的输入重载(但可以为其他 STL 迭代器重载)
- 创建集合向量作为类成员会在 c++ 中给出错误
- 如何重新分配(也称为集合)unique_ptr类成员?
- 更新成员集合使用STL给定输入收集
- 对集合调用成员方法
- C 集合构建器中类成员数组的2D数组大小
- C 模板功能在任何集合成员字段上迭代
- 实例化与unique_ptr的类集合成员
- 检查给定组中的成员身份的 SID 集合
- 创建集合成员(C )成员的每个置换和符号变化的集合
- 使用提升的集合中的成员函数代理
- 如果您在c++中更新一个集合的成员,该集合会自动更改顺序吗
- 计算不相交集合中的成员数
- 如何遍历类的实例集合并访问其模板成员
- 包含具有 CString 成员变量的类的集合仅存储第一个字母
- 我想从具有结构部分成员的集合中找到一个结构
- 具有单个成员的自定义结构(包装器)的集合(也是自定义结构)到单个成员的集合