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

C++自定义模板排序函数的std::function类型适配问题及解决方案

解决C++通用排序函数的类型适配问题

你遇到的核心问题是比较器的类型绑定过死,导致模板无法灵活适配不同类型的比较需求。让我们一步步拆解问题并修复它:

原代码的核心问题

原sorting函数的声明:

void sorting(vector<T>& files, int beginning, int end, std::function<bool(int, int)> compare)

这里有两个关键问题:

  • 硬编码了std::function<bool(int, int)>,意味着只能接收比较int类型的函数/lambda,对于double等其他类型,lambda的签名不匹配,会直接编译失败。
  • 即使改成std::function<bool(T, T)>,std::function的类型擦除会带来额外的性能开销,而且模板推导无法自动匹配lambda的具体类型,需要显式转换,不够灵活。

另外,原median_size函数也有小问题:返回类型是int,但应该返回T(因为处理的是vector<T>),而且参数传值会导致整个vector拷贝,效率低下。

修复方案

我们可以通过将比较器也作为模板参数来解决这个问题,这样编译器会自动推导比较器的具体类型(包括lambda的闭包类型),既避免类型擦除的开销,又能完美适配任意符合要求的比较逻辑。同时修正median函数的返回类型和参数传递方式。

修复后的完整代码

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <memory> // 为了std::make_unique

using std::vector;
using std::cout;
using std::swap;
using std::make_unique;

template <class T>
T median(const vector<T>& values, int beginning, int end) {
    T a = values[beginning], b = values[(end + beginning) / 2], c = values[end - 1];
    if ((a < b && a > c) || (a > b && a < c)) return a;
    else if ((b < a && b > c) || (b > a && b < c)) return b;
    else return c;
}

template <typename T, typename F>
void sorting(vector<T>& values, int beginning, int end, F compare) {
    int left = beginning, right = end;
    T pivot = median(values, beginning, end);
    while (left <= right) {
        while (compare(values[left], pivot)) left++;
        while (compare(pivot, values[right])) right--;
        if (left <= right) {
            swap(values[left], values[right]);
            left++;
            right--;
        }
    }
    // 递归处理子数组,优化边界判断逻辑
    if (beginning < right) sorting(values, beginning, right, compare);
    if (left < end) sorting(values, left, end, compare);
}

int main() {
    // 测试int类型数组排序
    vector<int> values{ 2135,2134,1236,21366,12312,2351232 };
    std::sort(std::begin(values), std::end(values),
        [](int a, int b) { return a < b; });
    cout << "Sorted int values:\n";
    for (auto value : values) cout << value << "\n";
    cout << "\n";

    // 演示lambda捕获智能指针
    auto p = make_unique<int>(65);
    cout << "Original pointer value: " << *p << "\n";
    auto lambda = [&p]() { cout << "Lambda captured value: " << *p << "\n"; };
    lambda();
    cout << "\n";

    // 测试double类型数组排序
    vector<double> values2{ 2135.2135,2134.12365,1236.11,1236.12,21366,12312,235122};
    sorting(values2, 0, values2.size() - 1, [](double a, double b) { return a < b; } );
    cout << "Sorted double values:\n";
    for (auto value : values2) cout << value << "\n";
}

关键修复点说明

  • 比较器模板化:新增模板参数F,让编译器自动推导比较器的类型(比如lambda的闭包类型),无需std::function,既高效又灵活。
  • 修正median函数:返回类型改为T,参数使用const vector<T>&避免不必要的拷贝,同时函数名改为更准确的median。
  • 安全的命名空间使用:替换using namespace std;为具体的using声明,避免命名空间污染。
  • 优化递归边界:原代码的边界判断right - beginning > 0简化为beginning < right,逻辑更清晰直观。

内容的提问来源于stack exchange,提问作者Michał Turek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:28:19