Reputation: 2127
It is possible to change the comparison method of a std::map after it has been created and initialized? Or maybe only after it has been created??
I want to alter somehow the behavior of a class that contains a map that I cannot change the definition. I want to change it's comparison behavior maybe by passing another map.
Upvotes: 6
Views: 4068
Reputation: 227608
It is not possible. But you can create a new map, with the alternative comparison criteria, and the two iterator constructor to instantiate the map using the elements from the first one.
bool C1(const K&, const K&);
bool C2(const K&, const K&);
std::map<K, V, C1> orig;
....
std::map<K, V, C2> alternative(orig.begin(), orig.end());
Upvotes: 1
Reputation: 477620
No, that is not possible. The comparator is part of the type of the map. The question is no different from asking whether you can change an int
to store floating point numbers.
More importantly, the ordering provided by the comparator is an integral part of the internal structure of the map. If you were to change the ordering, the data structure would no longer be in a consistent state. The only feasible option is to rebuild a new map from the old map's elements with respect to the new order, but that's already possible:
std::map<T, V, Comp1> m1 = /* ... */;
std::map<T, V, Comp2> m2(m1.begin(), m1.end());
Alternatively, you can make a second map of type std::map<std::reference_wrapper<T const>, std::reference_wrapper<V>, Comp2>
and populate it with references to the original map, but ordered according to Comp2
. In that case it is your own responsibility to maintain the two maps in sync. An advanced container like Boost.Multiindex can do this for you in a safe fashion.
Upvotes: 3
Reputation: 33655
Maybe it is possible, this is untested:
Have tested, and it is possible to do the above, however changing the comparison function if there are items in the tree can be disastrous...
Anyway - it all sounds too fishy....
Upvotes: 4
Reputation: 6128
No it is not possible, since it is compiled into the map via a template argument.
See: http://www.cplusplus.com/reference/map/map/ Compare is what you are looking for.
What are you trying to do?
Since you have the class in the hand you are using as Key, you could implement either the < operator or the compare function to react to context. Since you can pass a fully constructed object to the constructor as comparison function it should be possible to pass everything along to implement a context dependent compassion. The question is, why would you want to?
It is a bad idea to change the comparison of std::map while it runs, because it will result in undefined behavior. Simply based on the fact that the contents of std::map is "sorted" (probably a RB-tree). If you change the ordering function you will suddenly change logical order; but the map will not magically reorder itself. The next call to insert or find will probably not do what you expect.
Upvotes: 1