我有一个包含单个 .h
文件和多个 .cpp
文件的项目。头文件包含当前实现排序的命名空间 UF
(useful functions 的缩写)。
这是通过在 UF.cpp
中定义一个比较器来完成的,因此:
int compar_int_asc(const void *a, const void *b)
{
int aa = *((int *)a), bb = *((int *)b);
if (base_arr_int[aa] < base_arr_int[bb])
return -1;
if (base_arr_int[aa] == base_arr_int[bb])
return 0;
if (base_arr_int[aa] > base_arr_int[bb])
return 1;
}
目前qsort
需要访问的基数组base_arr_int
和上面的比较器函数在main.cpp
中声明,在 UF.cpp
中外部。
我在不同的类 SEP
中访问 qsort
,如下所示。首先,在 SEP.cpp
中,我外部 base_arr_int
。然后,如果 ratios[100]
是 SEP
本地的整数数组,我将在 SEP.cpp
中执行以下操作。
base_arr_int = ratios;
qsort(indices, 100, sizeof(int), UF::compar_int_asc);
这是实现多类 qsort 的最佳方式吗?
特别是,我想尽可能避免使用 main.cpp
中定义的全局变量。有没有其他设计?
最佳答案
全局变量的目的是象征性地将数组放置在自定义比较器中。为了消除全局变量,让我们从字面上将 ratio
放入自定义比较器中。为此,自定义比较器不能是普通函数或函数指针。它必须是一个函数对象。 std::sort
支持这一点。
让我们一步一步来。
所以,你有一个存储东西的数组。
int ratio[5] = {300, 400, 200, 500, 100};
但你不想直接排序。您创建了一个实际排序的索引数组。
int indice[5] = {0, 1, 2, 3, 4};
目标是对索引
进行排序。所以让我们写:
std::sort(indice, indice + 5);
但这还不是你想要的。您还需要传递自定义比较器 index_comp
,因为默认的小于比较器不是您所需要的。
std::sort(indice, indice + 5, index_comp);
剩下的工作就是如何编写index_comp
。其实很简单:lambda表达式
auto index_comp = [&ratio](int index_left, int index_right) { return ratio[index_left] < ratio[index_right]; };
此 lambda 表达式通过引用 ([&ratio]
) 捕获数组 ratio
。它有一个带两个索引的参数列表。主体以 ratio
比较两个实际对象。
如果您更喜欢老派的方式,lambda 表达式只是以下内容的语法糖:
class Compiler_Generated_Name
{
private:
int (&ratio)[5];
public:
Compiler_Generated_Name(int (&ratio_)[5]) : ratio(ratio_) {}
bool operator()(int index_left, int index_right)
{
return ratio[index_left] < ratio[index_right];
}
};
Compiler_Generated_Name index_comp(ratio);
完整代码:
#include <iostream>
#include <algorithm>
int main()
{
int ratio[5] = {300, 400, 200, 500, 100};
int indice[5] = {0, 1, 2, 3, 4};
auto index_comp = [&ratio](int index_left, int index_right) { return ratio[index_left] < ratio[index_right]; };
std::sort(indice, indice + 5, index_comp);
for (int i = 0; i < 5; ++i)
std::cout << ratio[indice[i]] << ' ';
}
关于c++ - 有没有办法避免使用全局变量来实现 qsort,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46416550/