使用宏"高阶函数"生成器在C中进行函数编程

for*_*ran 33 c functional-programming c-preprocessor

请注意,因为这是一个问题的地狱;-)

我想在C中使用模板函数进行泛型集合操作(​​如search,foreach等),同时保持编译器静态类型检查.当你使用像这个例子中的简单回调时,这是相当简单的:

#define MAKE_FOREACH(TYPE)\
void foreach_##TYPE (TYPE[n] array, int n, void(*f)(TYPE)) {\
  for(int i = 0; i < n; i++) {\
    f(array[i]);\
  }\
}
Run Code Online (Sandbox Code Playgroud)

所以你可以这样做:

MAKE_FOREACH(int)
MAKE_FOREACH(float)

void intcallback(int x){
  printf("got %d\n", x);
}

void floatcallback(float x){
  printf("got %f\n", x);
}

int main(){
  int[5] iarray = {1,2,3,4,5};
  float[5] farray = {1.0,2.0,3.0,4.0,5.0};
  foreach_int(iarray, 5, intcallback);
  foreach_float(farray, 5, floatcallback);
}
Run Code Online (Sandbox Code Playgroud)

如果我想用返回类型实现回调,例如创建一个"map"函数,我可以这样做:

#define MAKE_MAP(TYPE, RTYPE)\
RTYPE* map_##TYPE (TYPE[n] array, int n, RTYPE(*f)(TYPE)) {\
  RTYPE* result = (RTYPE*)malloc(sizeof(RTYPE)*n);\
  for(int i = 0; i < n; i++) {\
    result[i]=f(array[i]);\
  }\
}
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.当我希望我的回调函数接受任意数量的类型参数时,问题就出现了.

这个想法是这样的:

#define MAKE_MAP(TYPE, RTYPE, ...)\
RTYPE* map_##TYPE (TYPE[n] array, int n, RTYPE(*f)(TYPE, __VA_ARGS__), __VA_ARGS__)
/*this would work for the declaration (because just the types would be enough)
but the  parameter names are missing :-s*/ \
{\
  RTYPE* result = (RTYPE*)malloc(sizeof(RTYPE)*n);\
  for(int i = 0; i < n; i++) {\
    result[i]=f(array[i], /*here the names of the parameters, in order*/);\
  }\
}
Run Code Online (Sandbox Code Playgroud)

所以,正如你所看到的,我可以将map函数声明为:

MAKE_MAP(int, float, char)
Run Code Online (Sandbox Code Playgroud)

赠送:

float* map_int(int[n] array, int n, float(*f)(int, char), char);
Run Code Online (Sandbox Code Playgroud)

但我无法想象如何实现与预处理器一起传递的参数.在这里,我向您寻求帮助,想法和建议.

(顺便说一下,不要告诉我使用variadic函数作为模板并将va_list参数传递给回调,因为所有这些都是因为类型检查:-p)

Nik*_*sov 12

如果您使用的是Linux/BSD Unix,请查看queue(3)并查看/usr/include/sys/queue.h- 之前已完成:)