Reputation: 221
Suppose I have a map, key as char and value as integer. Based on the property of black-red tree, every time I insert a new pair, the map will be sorted by char. After all insertion, I want to sort my map again by its value(i.e. the integer number). My question is, can I do this by my own compare function? Here is the code:
sort(mymap.begin(), mymap.end(), MyComp);
class MyComp
{
public:
bool operator()(const pair<char, int>& x, const pair<char, int>& y) const
{
return x.second > y.second;
}
};
My code can not compile, but I do not know why I can't do this. Can anyone help me?
And further more, if this is not a good way to solve the problem, is there any other way to do this?
I can think of a way that is to create another map and insert again by exchange the value and key, it works but waste much more space. Thanks!
Upvotes: 2
Views: 961
Reputation: 44238
Sorting criteria for std::map
is set only once upon creation and you cannot change it later neither you can rearrange existing data inside your map. So if you need to resort your data differently you can use different container like boost::multi_index
that supports multiple cafeterias for sorting or copy data to another container and sort it.
Upvotes: 0
Reputation: 153820
You can't rearrange the elements of a std::map<K, V>
: the value type of this map is actually std::pair<K const, V>
and, thus, the elements are not Swappable as is required for std::sort()
.
You can, however, change the sorting criteria by customizing the predicate of the std::map<...>
itself:
std::map<K, V, Compare> m;
Note, however, that the comparison function in Compare
takes two K const&
as argument, rather than a std::pair<K const, V>
.
BTW, if you ever get an element from a std::map<K, V, ...>
, the value type is not std::pair<K, V>
but std::pair<K const, V>
. However, often the latter type implicitly converts into the former, i.e., you can call
void f(std::pair<char, int> const&) { ... }
with a std::pair<char const, int>
:
f(std::pair<char const, int>('a', 1));
This operation will, however, not just provide a reference to the original object but construct a new object. In the setup using char
and int
this isn't much of a problem but the conversion can be rather expensive, e.g., if one of the members is a std::string
.
Upvotes: 3