Как объявить указатель на функцию, которая возвращает указатель на функцию - PullRequest
0 голосов
/ 01 июня 2018

Как вы объявляете указатель на функцию, которая указывает на функцию с такими же параметрами, а также возвращает указатель на функцию с такими же параметрами.

т.е. funcPtr указывает на func1(int a, int b), иfunc1 возвращает указатель на другую функцию func2(int a, int b).func2 также возвращает указатель на функцию с той же сигнатурой, что и func1.

TYPE funcPtr = func1;
funcPtr = funcPtr(0, 1);

Как можно объявить funcPtr?Каким должен быть TYPE

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Это только пример без typedefs.Вы можете попытаться изменить параметры функций, но синтаксис ужасен и обычно бесполезен.

char (*(*((*foo)()))())()

foo - указатель на функцию, возвращающую указатель на функцию, возвращающую указатель на функцию, возвращающую символ

ИлиВы можете использовать typedefs

, например,

typedef int (*foo2)(int, int);

typedef foo2 (*foo1)(int, int);
typedef foo1 (*foo)(int, int);

или более общие

typedef int (*foo`n`)(int, int);
typedef foo`n' (*foo'n-1`)(int, int);

...

typedef foo2 (*foo1)(int, int);
typedef foo1 (*foo)(int, int);
0 голосов
/ 01 июня 2018

Я думаю, что реальная проблема в C состоит в том, что вы получаете бесконечное объявление , так как функция возвращает указатель на функцию, и этот указатель на функцию необходимо набрать для возврата указателя на функцию, к которой необходимо набрать....

Ниже приведены несколько шагов в таком бесконечном объявлении, просто чтобы показать, как объявление расширяется и расширяется:

int f0(int a) {
    return 1;
}
int (*f1(int a))(int) {
    return f0;
}
int (*(*f2(int a))(int))(int) {
    return f1;
}


Как решение для унаследованного кода, он может возвращать номер состояния, а таблица с функциями может использоваться для вызова функции, определенной для состояния, например:
#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
}
0 голосов
/ 01 июня 2018

Неразрешимая собственная ссылка

Это невозможно напрямую.Если вы попытаетесь определить тип указателя на функцию, где тип возвращаемого значения функции является ее собственным типом, вы столкнетесь с неразрешенной собственной ссылкой, для решения которой потребуется бесконечная рекурсия.

typedef funcType (*funcType)(void);

Возврат struct

Вместо этого можно объявить, что функция возвращает структуру, и структура может содержать указатель на такую ​​функцию.

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();

Возвращать другой тип указателя на функцию

Если вы предпочитаете строго придерживаться указателей, вам придется прибегнуть к определению функций, которые возвращают другой тип указателя на функцию.Таким образом, результат вызова должен быть приведен обратно к правильному типу указателя перед вызовом.

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();

Вернуть индекс

Вы могли бы вместо этогоопределите свои функции, чтобы возвращать индекс к таблице, которая представляет функцию, которая должна быть вызвана.

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()];

Это было поднято в комментариях и в ответ Павла , но представленздесь для полноты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...