我想使用一组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)
这是否会自动更改集合中的顺序?
这是否会自动更改集合中的顺序?
它不仅不会改变秩序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)
这将避免您的类型的额外副本和额外的分配/释放.