C syntax for functions returning function pointers

我们两清 提交于 2019-11-27 10:10:39

Start with your declaration for f1:

int (*f1)(float);

You want f2 to be a pointer to a function returning f1, so substitute f1 in the declaration above with the declaration for f2:

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

The declaration reads as

        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

You repeat the process for f3:

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

which reads as

          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

In C++, the miracle of templates can make this a tad easier.

#include <type_traits>

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

The same as with the typedef, only you place your function definition in place of its name.

Here's how f2 would look like:

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

You can do f3 as an exercise, since I'm assuming this is homework ;)

Just don't. It can be done, but it will be very confusing. Typedef's are there to ease writing and reading this short of code.

A function f that takes no arguments and returns a function pointer int (*)(float) would probably be something like (untested):

int (*f())(float);

Then for the rest you just need to keep adding parenthesis until it looks like lisp.

Learn the the right-left rule:

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

Use std::function:

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

or

typedef std::function<std::function<std::function<int(float)>(double)>(int)> f3;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!