Синтаксис C для функций, возвращающих указатели на функции

Рассмотрим следующие typedefs:

typedef int (*f1)(float);
typedef f1 (*f2)(double);
typedef f2 (*f3)(int);

f2 это функция, которая возвращает указатель на функцию То же самое сf3, но тип функции, указатель на которуюf3 возвращается, естьf2, Как я могу определитьf3 без typedefs? Я знаю, что typedefs - более понятный и понятный способ определенияf3, Однако мое намерение состоит в том, чтобы лучше понять синтаксис Си.

Ответы на вопрос(6)

УзнайтеПраво-левое правило:

The "right-left" rule is a completely regular rule for deciphering C declarations. It can also be useful in creating them.

использованиеstd::function:

typedef std::function<int(float)> f1;
typedef std::function<f1(double)> f2;
typedef std::function<f2(int)>    f3;

или же

typedef std::function<std::function<std::function<int(float)>(double)>(int)> f3;
Решение Вопроса

Начните с вашей декларации дляf1:

int (*f1)(float);

Ты хочешьf2 быть указателем на функцию, возвращающуюf1так подставьf1 в декларации выше с декларацией дляf2:

int (*      f1     )(float);
            |
      +-----+-----+
      |           |
      v           v
int (*(*f2)(double))(float);

Декларация гласит:

        f2                   -- f2
       *f2                   -- is a pointer
      (*f2)(      )          -- to a function
      (*f2)(double)          --   taking a double parameter
     *(*f2)(double)          --   returning a pointer
    (*(*f2)(double))(     )  --   to a function
    (*(*f2)(double))(float)  --     taking a float parameter
int (*(*f2)(double))(float)  --     returning int

Вы повторяете процесс дляf3:

int (*(*    f2    )(double))(float);
            |
        +---+----+
        |        |
        v        v
int (*(*(*f3)(int))(double))(float);

который читается как

          f3                           -- f3
         *f3                           -- is a pointer
        (*f3)(   )                     -- to a function
        (*f3)(int)                     --   taking an int parameter
       *(*f3)(int)                     --   returning a pointer
      (*(*f3)(int))(      )            --   to a function
      (*(*f3)(int))(double)            --     taking a double parameter
     *(*(*f3)(int))(double)            --     returning a pointer
    (*(*(*f3)(int))(double))(     )    --     to a function
    (*(*(*f3)(int))(double))(float)    --       taking a float parameter
int (*(*(*f3)(int))(double))(float);   --       returning int

В C ++ чудо шаблонов может сделать это немного проще.

#include <type_traits>

std::add_pointer<
    std::add_pointer<
        std::add_pointer<
            int(float)
        >::type(double)
    >::type(int)
>::type wow;

Просто не надо. Это можно сделать, но это будет очень запутанно. Typedef предназначен для облегчения написания и чтения этого короткого кода.

Функцияf который не принимает аргументов и возвращает указатель на функциюint (*)(float) вероятно будет что-то вроде (не проверено):

int (*f())(float);

Тогда для всего остального вам просто нужно продолжать добавлять скобки, пока они не будут похожи на шутки.

Как и в случае с typedef, только вы помещаете определение вашей функции вместо ее имени.

Вот какf2 будет выглядеть так:

typedef int (*(*f2)(double))(float);

Ты можешь сделатьf3 в качестве упражнения, так как я предполагаю, что это домашняя работа;)

Ваш ответ на вопрос