retornar - Función de retorno del tipo de puntero
punteros y vectores en c (7)
Creo que tienes tres opciones:
- Quédate con typedef. Al final del día, es el trabajo de typedef.
- Devuelve void * y el casting.
- Reconsidere su arquitectura de software. Quizás pueda compartir con nosotros lo que está tratando de lograr y ver si podemos orientarlo hacia una mejor dirección.
A menudo encuentro la necesidad de escribir funciones que devuelven punteros a funciones. Cada vez que lo hago, el formato básico que uso es:
typedef int (*function_type)(int,int);
function_type getFunc()
{
function_type test;
test /* = ...*/;
return test;
}
Sin embargo, esto puede volverse incómodo cuando se trata de una gran cantidad de funciones, por lo que me gustaría no tener que declarar un typedef para cada una (o para cada clase de funciones)
Puedo eliminar el typedef y declarar la variable local devuelta en la función como: int (*test)(int a, int b);
haciendo que la función del cuerpo se vea así:
{
int (*test)(int a, int b);
test /* = ...*/;
return test;
}
pero luego no sé qué configurar para el tipo de retorno de la función. Yo he tratado:
int(*)(int,int) getFunc()
{
int (*test)(int a, int b);
test /* = ...*/;
return test;
}
pero eso informa un error de sintaxis. ¿Cómo declaro el tipo de retorno para tal función sin declarar typedef para el puntero de función? ¿Es incluso posible? También tenga en cuenta que soy consciente de que parece que sería más limpio declarar typedefs, sin embargo, para cada una de las funciones, tengo mucho cuidado de estructurar mi código para que sea tan limpio y fácil de seguir como sea posible. La razón por la que me gustaría eliminar las definiciones de tipo es que a menudo solo se utilizan para declarar las funciones de recuperación y, por lo tanto, parecen redundantes en el código.
Dejaré esto aquí porque fue un poco más complicado que las respuestas ya dadas, ya que tiene un puntero a función
(int (__cdecl *)(const char *))
y devuelve un puntero a la función
(int (__cdecl *)(const char *))
#include <stdio.h>
int (*idputs(int (*puts)(const char *)))(const char *) {
return puts;
}
int main(int argc, char **argv)
{
idputs(puts)("Hey!");
return 0;
}
Este es un ejemplo estúpido, pero es simple y no da errores. Se trata de declarar funciones estáticas:
#include <stdio.h>
#include <stdlib.h>
void * asdf(int);
static int * hjkl(char,float);
main() {
int a = 0;
asdf(a);
}
void * asdf(int a) {return (void *)hjkl; }
static int * hjkl(char a, float b) {int * c; return c;}
Mientras envolvía algo de código C en las clases de C ++, tenía el mismo deseo que el póster original: devolver un puntero a una función desde una función sin tener que recurrir a la typedef
del prototipo de puntero de función. Encontré un problema con la corrección de C ++ const
que pensé que valía la pena compartir, incluso si es un poco fuera de tema (C ++) pero se relaciona directamente con la pregunta original: la sintaxis para devolver un puntero de función C sin recurrir a typedef
.
El siguiente código define una clase A
que almacena un puntero de función y lo expone al mundo exterior a través de la llamada a get_f()
. Esta es la función que debe devolver un puntero de función sin un typedef
.
El punto (que me get_f()
perplejo durante algún tiempo) fue cómo declarar que get_f()
era una función const
, es decir, no alteraría A
El código contiene 2 variantes: la primera utiliza un typedef para el prototipo de puntero de función, mientras que la segunda escribe todo por completo. El #if
cambia entre los dos.
#include <iostream>
int my_f(int i)
{
return i + 1;
}
#if 0 // The version using a typedef''ed function pointer
typedef int (*func_t)(int);
class A
{
public:
A(func_t f) : m_f(f) {}
func_t get_f() const { return m_f; }
private:
func_t m_f;
};
int main(int argc, char *argv[])
{
const A a(my_f);
std::cout << "result = " << a.get_f()(2) << std::endl;
}
#else // The version using explicitly prototyped function pointer
class A
{
public:
A(int (*f)(int)) : m_f(f) {}
int (*get_f() const)(int) { return m_f; }
private:
int (*m_f)(int);
};
int main(int argc, char *argv[])
{
const A a(my_f);
std::cout << "result = " << a.get_f()(2) << std::endl;
}
#endif
La salida esperada / deseada es:
result = 3
El punto clave es la posición del calificador const
en la línea:
int (*get_f() const)(int) { return m_f; }
Probablemente puedas hacer algo como:
int foo (char i) {return i*2;}
int (*return_foo()) (char c)
{
return foo;
}
Pero Dios, espero nunca tener que depurar tu código ...
Puede escribir el siguiente código (solo funciona en C ++ 11 y superior):
//C++11
auto func(...) {
int (*fptr)(...) ret = ...
//Do sth.
return ret;//C++11 compiler will automatically deduce the return type for you
}
O, si no le gusta la deducción automática del tipo de retorno, puede especificar el tipo al final de la función (igual que arriba, solo en C ++ 11 y superior):
//C++11
auto func(...) -> int (*)(...) { /* Do sth. */ }
int (*getFunc())(int, int) { … }
Eso proporciona la declaración que solicitó. Además, como señala ola1olsson , sería bueno insertar void
:
int (*getFunc(void))(int, int) { … }
Esto indica que getFunc
no puede tomar ningún parámetro, lo que puede ayudar a evitar errores, como que alguien escriba inadvertidamente getFunc(x, y)
lugar de getFunc()(x, y)
.