You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将比较器作为函数参数传递?C++归并排序传参报错求解

解决归并排序比较器传递的C3867错误及相关问题

首先,你的代码存在几个关键问题,导致了C3867错误和潜在的逻辑错误,我来一步步帮你梳理和修正:

1. 核心错误:比较器传递方式不对

你尝试传递Point::CompareXCoordinate::operator(),这是类的非静态成员函数,这类函数必须依赖一个类的实例才能调用,直接传成员函数名的语法是错误的(C3867错误就是在提示你需要用&取地址,但即使取了地址,后续调用也需要绑定实例,非常麻烦)。

正确的做法是:直接传递CompareXCoordinate类的实例,因为它是一个仿函数类(重载了operator()),而你的mergeSort模板参数Comparator设计就是接受可调用对象(包括仿函数实例、lambda、普通函数指针等)。

2. 额外错误:索引参数传递错误

你的mergeSort函数定义中,left和right是int类型的数组索引,但你调用时传了points.begin()和points.end()(迭代器),这会导致类型不匹配,也是需要修正的点。

3. 逻辑错误:归并排序的终止条件错误

你原代码里的if (cmp(left,right))完全不对!left和right是数组索引,判断是否需要拆分递归应该用索引的大小比较(left < right),而不是用元素比较器去比较两个整数索引,这会导致排序逻辑完全混乱。

修正后的完整代码示例

第一步:修正mergeSort的模板定义和逻辑

#include <vector>
// 假设Point类的定义如下(补充必要的部分)
class Point {
private:
    int x;
public:
    int getX() const { return x; }
    // 你的其他Point成员...
};

// 修正后的mergeSort模板
template <typename Comparable, typename Comparator>
void mergeSort(vector<Comparable>& a, vector<Comparable>& tmpArray, int left, int right, Comparator cmp) {
    // 正确的终止条件:索引left小于right时才继续拆分
    if (left < right) {
        int center = (left + right) / 2;
        mergeSort(a, tmpArray, left, center, cmp);
        mergeSort(a, tmpArray, center + 1, right, cmp);
        // 假设你的merge函数已经正确实现,会使用cmp来比较元素
        merge(a, tmpArray, left, center + 1, right, cmp);
    }
}

// 你的自定义比较器类
class CompareXCoordinate {
public:
    bool operator()(const Point& p1, const Point& p2) const {
        return p1.getX() < p2.getX();
    }
};

第二步:正确调用mergeSort

在mainDriver.cpp中:

#include <vector>
// 引入Point、mergeSort、CompareXCoordinate的定义

int main() {
    // 初始化Point对象的vector
    std::vector<Point> points = {/* 你的Point实例 */};
    // 临时数组需要和原数组同大小,避免merge时越界
    std::vector<Point> tempArr(points.size());
    
    // 创建比较器实例
    CompareXCoordinate xCoordComparator;
    // 传递正确的索引(0到size-1)和比较器实例
    mergeSort(points, tempArr, 0, points.size() - 1, xCoordComparator);
    
    // 或者用lambda表达式替代自定义比较器类,更简洁
    // mergeSort(points, tempArr, 0, points.size() - 1, [](const Point& p1, const Point& p2) {
    //     return p1.getX() < p2.getX();
    // });
    
    return 0;
}

为什么这样能解决问题?

  • 仿函数实例xCoordComparator是一个可调用对象,直接传给mergeSort后,在merge函数中可以直接用cmp(p1, p2)的方式调用它的operator(),符合模板的设计预期。
  • 传递0和points.size()-1作为索引,匹配了mergeSort函数的参数类型要求。
  • 修正后的终止条件left < right保证了归并排序的递归拆分逻辑正确。

内容的提问来源于stack exchange,提问作者Amor Diaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:23:09