parametros - Cómo declarar un puntero de función que devuelve un puntero de función
punteros en c++ definicion (3)
Auto-referencia irresoluble
Esto no es posible directamente. Si intenta definir un tipo de puntero de función donde el tipo de retorno de la función es su propio tipo, se encontrará con una auto-referencia no resuelta, y eso requeriría una recursión infinita para resolver.
typedef funcType (*funcType)(void);
Devolver una struct
En su lugar, puede declarar que la función devuelve una estructura, y la estructura puede contener un puntero a dicha función.
struct func {
struct func (*func) (void);
};
struct func foo (void);
struct func bar (void);
struct func foo (void) { return (struct func){ bar }; }
struct func bar (void) { return (struct func){ foo }; }
...
struct func funcPtr = { foo };
funcPtr = funcPtr.func();
Devuelve un tipo de puntero de función diferente
Si prefiere atenerse a los punteros estrictamente, tendrá que recurrir a la definición de funciones que devuelven un tipo de puntero de función diferente. Por lo tanto, el resultado de la llamada tendría que volver al tipo de puntero adecuado antes de ser invocado.
typedef void (*funcPtrType)(void);
typedef funcPtrType funcType(void);
funcType foo;
funcType bar;
funcPtrType foo (void) { return (funcPtrType)bar; }
funcPtrType bar (void) { return (funcPtrType)foo; }
...
funcType *p = foo;
p = (funcType *)p();
Devolver un índice †
En su lugar, podría definir sus funciones para devolver un índice a una tabla que represente la función que debe invocarse.
enum funcEnum { fooEnum, barEnum };
typedef enum funcEnum (*funcType)(void);
enum funcEnum foo (void) { return barEnum; }
enum funcEnum bar (void) { return fooEnum; }
funcType funcTable[] = { [fooEnum] = foo, [barEnum] = bar };
...
funcType p = funcTable[fooEnum];
p = funcTable[p()];
† Esto se planteó en los comentarios y en la respuesta de Paul , pero se presentó aquí para completar.
Cómo declarar un puntero de función que apunta a una función que tiene los mismos parámetros y también devuelve un puntero a una función con los mismos parámetros.
ie funcPtr
apunta a func1(int a, int b)
, y func1
devuelve un puntero a otra función func2(int a, int b)
. func2
también devuelve un puntero a función con la misma firma que func1
.
TYPE funcPtr = func1;
funcPtr = funcPtr(0, 1);
¿Cómo se declara funcPtr
? ¿Qué debe ser TYPE
?
Creo que el verdadero problema en C es que se obtiene una declaración infinita ya que la función devuelve un puntero a función y ese puntero a función debe escribirse para devolver un puntero a función que debe escribirse a ...
Los siguientes son algunos pasos en una declaración tan infinita, solo para mostrar cómo la declaración se expande y expande:
int f0(int a) {
return 1;
}
int (*f1(int a))(int) {
return f0;
}
int (*(*f2(int a))(int))(int) {
return f1;
}
Como solución para el código heredado, puede devolver un número de estado y se puede usar una tabla con funciones para llamar a la función definida para el estado, por ejemplo:
#define STATE0 0
#define STATE1 1
int fx1(int a);
int fx2(int a);
int (*ftab[])(int) = {
fx1,
fx2
};
void examplefunc(void)
{
int x = ftab[STATE1](3); // example of calling function from table
}
Esto solo un ejemplo sin typedefs. Puedes intentar cambiar los parámetros de las funciones, pero la sintaxis es horrible y, por lo general, inútil.
char (*(*((*foo)()))())()
foo es puntero a la función que devuelve el puntero a la función que devuelve el puntero a la función que devuelve char
O puedes usar typedefs
por ejemplo
typedef int (*foo2)(int, int);
typedef foo2 (*foo1)(int, int);
typedef foo1 (*foo)(int, int);
o mas general
typedef int (*foo`n`)(int, int);
typedef foo`n'' (*foo''n-1`)(int, int);
...
typedef foo2 (*foo1)(int, int);
typedef foo1 (*foo)(int, int);