如果您在c ++中更新集合的成员,该集合是否会自动更改顺序?

mei*_*nub 3 c++ set

我想使用一组S类型node,我想操纵集合中的成本部分并按以下顺序对集合进行排序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;
Run Code Online (Sandbox Code Playgroud)

这是否会自动更改集合中的顺序?

Bar*_*rry 6

这是否会自动更改集合中的顺序?

它不仅不会改变秩序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);
Run Code Online (Sandbox Code Playgroud)

这无疑是相当繁琐的.


有一项提案(P0083R2)将来会对此进行改进.


C++更新17:该提案已被接受.现在你要使用extract():

auto node = S.extract(vertex);
node.value().cost = 200;
S.insert(std::move(node));
Run Code Online (Sandbox Code Playgroud)

这将避免您的类型的额外副本和额外的分配/释放.