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

In my C ++ program, I am trying to sort my cards by value, not by key.

From this question , it seems obvious 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 a sample code where I am trying 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 result:

About Addition: A: 1
Item added normally
The set has size: 1
About Addition: B: 2
Segmentation Error: 11

I noticed that things are crashing when I go to add a second item. I found this to happen because now I need to call my sort routine, compareCounts .

The fix is ​​to change this line:

 set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter; 

:

 set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter(compareCounts); 

Why do I need to specify compareCounts sort routine compareCounts ? Doesn't the compiler already know about this from my type definition?

+6
source share
1 answer
 set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter; 

You never specified which comparator should use set . Change the above line to

 set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter(compareCounts); 

Without specifying a comparator, set defaults to building one ( nullptr ), and when it tries to use a comparator to insert the second element, your code will work.

You should just use a functor instead of a function pointer

 struct compareCounts { bool operator()(const pair<string, size_t> &lhs, const pair<string, size_t> &rhs) const { return lhs.second > rhs.second; } }; set <pair<string, size_t>, compareCounts> sorted_counter; 
+6
source

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


All Articles