在我的C ++程序中,我试图按值而不是按键对地图进行排序。
从this question来看,似乎很清楚,这样做的方法是创建一个集合,其元素是成对的,并且由我自己的less-than函数排序。
以下是我尝试执行此操作的示例代码:
#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;
}
这是输出:
即将添加:A:1
元素添加确定
套装尺寸:1
即将补充:B:2
分段错误:11
我注意到当我添加第二个元素时,事情会崩溃。我发现这种情况正在发生,因为现在需要调用我的排序子例程compareCounts
。
修复是改变这一行:
set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter;
到此:
set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter(compareCounts);
为什么我需要两次指定排序子程序compareCounts
?编译器是否已经从我的类型定义中知道了它?
答案 0 :(得分:6)
set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter;
您从未指定set
实际应使用的比较器。将上面的行更改为
set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter(compareCounts);
如果没有指定比较器,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;