Зачем мне нужно повторять процедуру сортировки при объявлении std:: set?

В моей программе на С++ я пытаюсь сортировать свои карты по значению, а не по ключу.

Из этого вопроса, кажется очевидным, что способ сделать это - создать набор, элементы которого являются парами и которые сортируются по моей собственной меньше-чем функции.

Вот пример кода, где я пытаюсь это сделать:

#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;
}
</string,></string,></string,></pair<string,></string,></string,></string,></string></iostream></set></map>

Вот результат:

О добавлении: A: 1 Элемент добавлен нормально Набор имеет размер: 1 О добавлении: B: 2 Ошибка сегментации: 11

Я заметил, что вещи рушится, когда я иду добавить второй элемент. Я обнаружил, что это происходит, потому что теперь нужно вызвать мою подпрограмму сортировки, compareCounts.

Исправление состоит в том, чтобы изменить эту строку:

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

:

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

Почему мне нужно дважды указывать подпрограмму сортировки compareCounts? Разве компилятор уже не знает об этом из моего определения типа?

1 ответ

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

Вы никогда не указывали, какой компаратор должен использовать set. Измените приведенную выше строку на

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

Без указания компаратора set по умолчанию строит один (nullptr), и когда он пытается использовать компаратор для вставки второго элемента, ваш код сработает.

Вы должны просто использовать функтор вместо указателя функции

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;
</pair<string,></string,></string,>

licensed under cc by-sa 3.0 with attribution.