How to define std :: set to "update" its order?

If the value of an element in the set changes, the order may already be incorrect. As shown in this small program:

#include <algorithm> #include <iostream> #include <set> #include <string> struct Comp { bool operator()(const std::string * lhs, const std::string * rhs) { return *lhs < *rhs; } }; int main() { typedef std::set<std::string*, Comp> MySet; MySet mySet; std::string * a = new std::string("a"); mySet.insert(a); std::string * c = new std::string("c"); mySet.insert(c); std::string * b = new std::string("b"); mySet.insert(b); for (MySet::iterator it = mySet.begin(); it != mySet.end(); ++it) { std::cout << *(*it) << std::endl; } // Ouput has correct order: // a // b // c *b = "z"; std::cout << std::endl; std::string * d = new std::string("d"); mySet.insert(d); for (MySet::iterator it = mySet.begin(); it != mySet.end(); ++it) { std::cout << *(*it) << std::endl; } // Output no longer ordered correctly: // a // d // z // c return 0; } 

How can I say that the set "updates" the internal sort?

+4
source share
5 answers

A very similar topic here (although not exactly repeating, because you keep pointers to mutable objects with a custom mapping):

What happens when the std :: set element changes?

Basically, do not do what you are trying to do. Instead, when you want to change the object that set contains a pointer to, first delete the pointer, then change the object, then reinsert the pointer.

+9
source

You just can't. If you put an element in a set, you should not change the element so that it changes order. If you need to change an element in this way, you need to remove it from the set (set :: erase) and reinsert the new element (std :: insert) with a new value.

+5
source

If the value of an element in a set changes

Stop! It cannot be legally.

std::set provides no way to do what you ask for, because it is already a prerequisite that manual reordering will never be necessary.

+2
source

It is worth noting that if you are using vs 2008, the std::set implementation supports non-constant iterators, which makes the code you describe successfully compiled using this library. In other implementations of stl (for example sgi ), set::const_iterator and set::iterator are of the same type, which complains about the explicit definition of a new key value.

+1
source

Copy it into yourself using another comparison predicate.

 std::set MySet(); /* add entries*/ MySet = std::set(MySet.begin(), MySet.end(), Comp); 

This is usually used to indicate another comparison operation, for example, to sort using another part of the stored class / structure.

0
source

Source: https://habr.com/ru/post/1286507/


All Articles