de pago con cuidado porque este es un infierno de una pregunta ;-)La programación funcional en C con macro generadores "Superior" función de orden
quiero usar las funciones de plantilla para las acciones de cobro genéricos (como la búsqueda, foreach, etc. .) en C mientras se mantiene la comprobación del tipo estático del compilador. Es bastante sencillo, mientras que usted está utilizando las devoluciones de llamada simples, como en este ejemplo:
#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]);\
}\
}
para que pueda hacer cosas como:
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 Me gustaría poner en práctica las devoluciones de llamada con tipos de retorno, para ejemplo para hacer una función de "mapa", podría hacer:
#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]);\
}\
}
Hasta ahora, muy bien. El problema viene ahora, cuando quiero que mis funciones de devolución de llamada acepten cualquier cantidad de argumentos escritos.
La idea es algo así como:
#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*/);\
}\
}
así, como se puede ver, pude declarar una función de mapa como:
MAKE_MAP(int, float, char)
dando:
float* map_int(int[n] array, int n, float(*f)(int, char), char);
pero no puedo entender cómo implementar el parámetro que pasa con el preprocesador. Aquí es donde pido su ayuda, ideas y sugerencias.
(Por cierto, no me diga que utilizar una función variadic como plantilla y pasar un argumento va_list a la devolución de llamada, porque todo esto era debido a la :-p chequear el tipo)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡SI QUIERO EMPUJAR UN POCO MÁS PEQUEÑO, ESTE PEGÓGENO CUADRADO SE ME ENCUENTRE EN MI AGUJERO REDONDO !!!! – mquander
Felicitaciones por etiquetar este "preprocesador-abuso". Estoy pensando en cómo escribiría una macro MAKE_PROGRAM(). –
Este ciertamente * es * abuso de preprocesador, pero ¿no es la meta-programación de plantillas tan de moda realmente solo el abuso del sistema de plantillas de C++ también? A veces la única respuesta sensata * es * para empujar la herramienta al borde de su usabilidad. – RBerteig