我有一个边数组,它被定义为C风格的双精度数组,其中每4个双精度定义一个边,如下所示:
double *p = ...;
printf("edge1: %lf %lf %lf %lf\n", p[0], p[1], p[2], p[3]);
printf("edge2: %lf %lf %lf %lf\n", p[4], p[5], p[6], p[7]);
Run Code Online (Sandbox Code Playgroud)
所以我想用std::sort()
边长来对它进行排序.如果是struct Edge { double x1, y1, x2, y2; }; Edge *p;
,我会很高兴.
但在这种情况下,double数组的块大小不是由指针类型表示的.qsort()
允许您显式指定块大小,但通过指针类型std::sort()
推断块大小.
出于性能原因(内存使用和CPU),让我们说创建新数组或以某种方式转换数组是不可取的.出于性能原因,让我们说我们确实想要使用std::sort()
而不是qsort()
.
是否可以std::sort()
在转换数据时不浪费单个CPU周期进行调用?
一个明显的方法是尝试强制转换指针:
double *p = ...;
struct Edge { double arr[4]; };
Edge *p2 = reinterpret_cast<Edge*>(p);
std::sort(...);
Run Code Online (Sandbox Code Playgroud)
但是如何确保数据正确对齐?另外,如何确保它始终在所有平台和架构上正确对齐?
或者我可以使用typedef double[4] Edge;
?
我希望能够将一个函数一般地传递给C 中的一个函数。我已经使用 C 几年了,我知道实现正确的闭包和高阶函数的障碍。这几乎是不可逾越的。
我搜索了 StackOverflow 以查看其他消息来源对此事的看法:
...除了使用可变参数或程序集之外,没有人有一个银弹一般的答案。我没有汇编的骨头,但如果我能在宿主语言中有效地实现一个特性,我通常会尝试。
我喜欢高阶函数,但我会在紧要关头满足于委托。我怀疑通过类似下面的代码,我可以在 C 中获得一个可行的委托实现。
想到了这样的实现:
enum FUN_TYPES {
GENERIC,
VOID_FUN,
INT_FUN,
UINT32_FUN,
FLOAT_FUN,
};
typedef struct delegate {
uint32 fun_type;
union function {
int (*int_fun)(int);
uint32 (*uint_fun)(uint);
float (*float_fun)(float);
/* ... etc. until all basic types/structs in the
program are accounted for. */
} function;
} delegate; …
Run Code Online (Sandbox Code Playgroud)