Mac OSX下std::greater<int>()配合partial_copy_sort报错:无匹配函数
解决std::greater()在map中查找前k大值时的编译错误
你这明显是踩了类型不匹配的坑——咱们先把错误根源说清楚:
你用的std::greater<int>()是专门用来比较int类型的,但std::map的迭代器解引用后得到的是std::pair<const Key, int>(假设你的map是map<某键类型, int>)。当你把这个比较器传给算法(比如partial_sort、nth_element这类)时,算法会尝试用它去比较两个pair对象,可std::greater<int>根本不知道怎么处理pair,自然就会抛出"no matching function"的编译错误。
下面给你两种适配旧版C++的解决方案:
方案1:自定义比较器(C++03及以上可用)
如果是C++03环境没法用lambda,就写一个自定义函数对象,专门比较map元素的value部分:
#include <map> #include <vector> #include <algorithm> #include <iostream> // 假设你的map是map<string, int>,键类型不同的话替换成对应类型即可 struct CompareMapValueDesc { bool operator()(const std::pair<std::string, int>& a, const std::pair<std::string, int>& b) const { // 按value降序排列,这样前k个就是值最大的元素 return a.second > b.second; } }; int main() { std::map<std::string, int> my_map = {{"a", 10}, {"b", 30}, {"c", 20}, {"d", 50}}; int k = 2; std::vector<std::pair<std::string, int>> top_k_elements; top_k_elements.reserve(k); // 用partial_sort_copy提取前k个最大的元素 std::partial_sort_copy(my_map.begin(), my_map.end(), top_k_elements.begin(), top_k_elements.end(), CompareMapValueDesc()); // 提取并输出键 for (const auto& elem : top_k_elements) { // 输出结果:d、b std::cout << elem.first << std::endl; } return 0; }
方案2:用Lambda表达式(C++11及以上可用)
如果编译器支持C++11或更高版本,用lambda会更简洁,不用单独写函数对象:
#include <map> #include <vector> #include <algorithm> #include <iostream> int main() { std::map<std::string, int> my_map = {{"a", 10}, {"b", 30}, {"c", 20}, {"d", 50}}; int k = 2; std::vector<std::pair<std::string, int>> top_k_elements; top_k_elements.reserve(k); std::partial_sort_copy(my_map.begin(), my_map.end(), top_k_elements.begin(), top_k_elements.end(), [](const auto& lhs, const auto& rhs) { return lhs.second > rhs.second; }); for (const auto& elem : top_k_elements) { std::cout << elem.first << std::endl; } return 0; }
额外提醒
std::map本身是按键的升序/降序排序的,它不会自动维护value的顺序,所以必须用partial_sort_copy、nth_element这类算法来筛选value最大的前k个元素。如果k很小,也可以手动遍历map维护一个大小为k的最小堆,效率可能更高~
内容的提问来源于stack exchange,提问作者aquaflamingo
相关产品推荐
相关产品推荐

