所以,我有一个编写程序来测试不同排序算法的速度的任务,其中一个是好的qsort
。我需要传递一个比较器,但不是它所期望的那个,但是布尔a-la std::less
,我知道要使用它以便qsort接受它,我需要实际传递类似{ {1}} ---这样,它的范围为less(b, a) - less(a,b)
并产生我需要的东西。
问题是:我不知道如何实际做到这一点!我试图使用lambda ---和(因为我需要捕获比较器而qsort无法处理这个)它失败了。我试图创建另一个将比较器转换为[-1; 1]
的函数:
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))
,但无法弄清楚如何。
所以我已经挣扎了一个小时,而且我已经没有接近解决方案了。这样做的正确方法是什么?
答案 0 :(得分:2)
你可以尝试这样的事情。 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");
}
答案 1 :(得分:1)
您无法通过cmp
将make_comparator
传递给qsort
。您最好的选择是将函数指针设置为正确的函数。
bool (*comp)(int a, int b) = nullptr;
int make_comparator(const void* a, const void* b) {
return (int)comp(*(int*)b, *(int*)a) - (int)comp(*(int*)a, *(int*)b);
}
然后将comp
设置为有效的函数指针
comp = <some function pointer>;
在致电qsort
之前。
qsort(ptr, count, size, make_comparator);
如果您选择遵循此方法,请务必在make_comparator
中添加检查,以防止在未设置为有效功能时调用cmp
。
int make_comparator(const void* a, const void* b) {
if ( comp == nullptr )
{
// Deal with error
}
return (int)comp(*(int*)b, *(int*)a) - (int)comp(*(int*)a, *(int*)b);
}