Consider the following typedefs :
typedef int (*f1)(float);
typedef f1 (*f2)(double);
typedef f2 (*f3)(int);
f2
is a function
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;
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.
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
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;
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.