Thursday, 22 August 2013

Why do I need to repeat the sorting subroutine when declaring a std::set?

Why do I need to repeat the sorting subroutine when declaring a std::set?

I have a C++ program where I am trying to sort my maps by value, rather
than by key.
From this question STL map--> sort by value?, it seems clear that the way
to do this is to create a set whose elements are pairs and which are
sorted by my own less-than function.
Here is some sample code where I try to do this:
#include <map>
#include <set>
#include <iostream>
#include <string>
using namespace std;
bool compareCounts(const pair<string, size_t> &lhs, const pair<string,
size_t> &rhs);
int main (int argc, char *argv[]) {
map <string, size_t> counter = { {"A", 1}, {"B", 2}, {"C", 3} };
set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter;
for (map<string, size_t>::iterator it = counter.begin(); it !=
counter.end(); ++it) {
cout << "About to add: " << it->first << ":" << it->second
<< endl;
auto ret = sorted_counter.insert(*it);
if (! ret.second) {
cout << "ERROR adding this element!" << endl;
} else {
cout << "Element added ok" << endl;
}
cout << "Set is of size: " << sorted_counter.size() << endl;
}
return 0;
}
bool compareCounts(const pair<string, size_t> &lhs, const pair<string,
size_t> &rhs) {
return lhs.second > rhs.second;
}
Here is the output:
About to add: A:1
Element added ok
Set is of size: 1
About to add: B:2
Segmentation fault: 11
I notice that things come crashing down when I go to add the second
element. I found that this is happening because it is now necessary to
call my sorting subroutine, compareCounts.
The fix was to change this line:
set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter;
to this:
set <pair<string, size_t>, decltype(compareCounts) *>
sorted_counter(compareCounts);
Why do I need to specify the sorting subroutine compareCounts twice?
Doesn't the complier already know from my type definition?

No comments:

Post a Comment