Faites attention avec soin, car c'est un enfer d'une question ;-)
Je veux utiliser un modèle de fonctions génériques sont une collection d'actions (comme la recherche, foreach, etc.) en C, tout en maintenant compilateur de vérifier le type statique. Il est assez simple alors que vous êtes en utilisant de simples rappels comme dans cet exemple:
#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]);\
}\
}
ainsi, vous pouvez faire des choses comme:
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);
}
Si je tiens à mettre en œuvre des rappels avec des types de retour, par exemple pour faire une "carte" de la fonction, j'ai pu faire:
#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]);\
}\
}
Pour l'instant, donc bon. Le problème vient maintenant, quand je veux mes fonctions de rappel à accepter n'importe quel nombre de tapé arguments.
L'idée est quelque chose comme:
#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*/);\
}\
}
donc, comme vous pouvez le voir, je pourrais déclarer une fonction map comme:
MAKE_MAP(int, float, char)
donner:
float* map_int(int[n] array, int n, float(*f)(int, char), char);
mais je ne peux pas comprendre comment mettre en œuvre le passage de paramètres avec le préprocesseur. C'est là que je demande votre aide, des idées et des suggestions.
(En passant, ne me dites pas d'utiliser un variadic de la fonction en tant que modèle, et en passant une va_list argument à la fonction de rappel, parce que tout ça était à cause de la vérification de type :-p)