c++ - 如何将比较器 a-la std::less 传递给 C 风格的 Qsort?

标签 c++ lambda compare qsort

所以,我有一项任务是编写一个程序来测试不同排序算法的速度,其中之一是很好的旧qsort。我需要向它传递一个比较器,但不是它期望的那个,而是一些 bool 值 a-la std::less,我知道要使用它以便 qsort 接受它,我需要实际上将它传递给 less(b, a) - less(a,b) --- 这样,它的范围为 [-1; 1] 并生成我需要的内容。

问题是:我不知道该怎么做!我尝试使用 lambda --- 并且(因为我需要捕获比较器而 qsort 无法处理)它失败了。我试图创建另一个函数,将我的比较器转换为 qsort 的:

int make_comparator(const void* a, const void* b) {
    return (int)comp(*(int*)b, *(int*)a) - (int)comp(*(int*)a, *(int*)b);
}

但我不知道如何实际将 comp 传递给它(因为我不能只写 qsort(..., make_comparator(comp, a, b)) ,我可以吗?)。我尝试使用模板来传递 comp,但不知道该怎么做。

所以我已经为此苦苦挣扎了将近一个小时,但我距离解决方案还差得很远。执行此操作的正确方法是什么?

最佳答案

你可以尝试这样的事情。 qsort_friendly_comparator 只是比较器对象的包装器。唯一的缺点是您必须手动指定比较器类型及其参数类型。

#include <functional>
#include <cstdlib>
#include <cstdio>

// Assumes Comparator take two arguments of the same type and returns a bool.
// Have to manually specify the ArgType because it is tricky to deduce without
// excessive template magic.
template <typename Comparator, typename ArgType>
int qsort_friendly_comparator(const void *first, const void *second)
{
  Comparator comp;

  return (int)comp(*(ArgType*)second, *(ArgType*)first) -
         (int)comp(*(ArgType*)first,  *(ArgType*)second);
}

int main() {
  int data[] = {2, 1, 3, 0}; 

  qsort(data,
        /*num_elem=*/4,
        /*size_of_elem=*/sizeof(int),
        &qsort_friendly_comparator<std::less<int>, int>);

  for (int i = 0; i < 4; i++) {
    printf("%d ", data[i]);
  }
  printf("\n");
}

关于c++ - 如何将比较器 a-la std::less 传递给 C 风格的 Qsort?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35008267/

相关文章:

c++ - 类对象的 vector 是如何初始化的

c# - 从 lambda 表达式访问属性的 HtmlHelper 方法之间的区别

algorithm - 我如何深入比较 2 个 Lua 表,它们可能有也可能没有表作为键?

python - 在 Python 中从选定的列表元素中查找最大的数字

javascript - AngularJS 与 ReactJS

c++ - 在 C++ 中使用映射器处理派生类创建

c++ - 将 int[2] 转换为 long

C++ 字符串像人一样排序?

vb.net - 尝试使用 VB.NET Lambda 而不是迭代器

c++11 - std::move 与 lambda 中的 std::shared_ptr