I have a std::set<Foo>, and I’d like to update some value of
an existing element therein. Note that the value I’m updating does not change the order in the set:
#include <iostream>
#include <set>
#include <utility>
struct Foo {
Foo(int i, int j) : id(i), val(j) {}
int id;
int val;
bool operator<(const Foo& other) const {
return id < other.id;
}
};
typedef std::set<Foo> Set;
void update(Set& s, Foo f) {
std::pair<Set::iterator, bool> p = s.insert(f);
bool alreadyThere = p.second;
if (alreadyThere)
p.first->val += f.val; // error: assignment of data-member
// ‘Foo::val’ in read-only structure
}
int main(int argc, char** argv){
Set s;
update(s, Foo(1, 10));
update(s, Foo(1, 5));
// Now there should be one Foo object with val==15 in the set.
return 0;
}
Is there any concise way to do this? Or do I have to check if the element is already there, and if so, remove it, add the value and re-insert?
Since
valis not involved in comparison, it could be declaredmutableThis implies that the value of
valmay change in a logically-const Foo, which means that it shouldn’t affect other comparison operators etc.Or you could just remove and insert, that takes O(1) additional time (compared to accessing and modifying) if insertion uses the position
just beforejust after the old one as the hint.Something like: