Typedef'ing function * signature * (not a pointer to) so that it can be reused?

EDIT: MOTIVATION

Suppose I define a Handler class as

class Handler { public: class Message { /*...*/ }; typedef int (*Callback)(Message *msg); void registerCallback(int msgclass, Callback f); }; 

Customer can perform

 int f1(Handler::Message *msg) { /* handle message */ } int f2(Handler::Message *msg) { /* handle message */ } int main(){ Handler h; h.registerCallback(1, f1); h.registerCallback(2, f2); // .... } 

The compiler does verify that f1 and f2 are appropriate parameters for registerCallback , however, for the client, correctly determine f1 and f2 . Since I haveready typedef ed Callback , I would like the client to be able to use it.

End edit

I would like to do something like this:

 typedef int arithmetic(int i, int j); arithmetic sum { return i+j; } arithmetic max { return (i>j)? i:j; } // etc. 

However both

 arithmetic sum arithmetic sum() 

not compiled as well as this

 arithmetic sum(int i, int j) 

which gives a compiler error

func.cpp: 4: error: 'sum is declared as a function returning a function

I want me to want a Handler class that provides a typedef for the callback function that it accepts , including a list of parameters .

+6
c ++ syntax typedef function-pointers
source share
5 answers

Firstly, you did not type a signature. A signature is all that identifies a single function. It contains the namespace / function class, etc.

What you typedef'ed is a type of function. For example, when you typedef int inttype , which typedefs type int , you typedef'ed the type of the function.

You can use typedef-name to declare only functions.

 arithmetic max; // valid 

But it cannot be used to define functions. To define functions you need to provide a list of parameters literally and manually. Reasons include specifying parameter names (and possibly other more technical reasons. C ++ 0x introduces arithmetic max {}; which will receive a specific initialization value).

+9
source share

I will give you the classic C answer without resorting to the newfangled C ++ 0x toys. Let's start by defining a function prototype:

 typedef int TWO_ARG_FUNC(int x, int y); 

You can use this prototype when receiving a function pointer, for example:

 void blah(TWO_ARG_FUNC* funcPtr); 

... or when directly declaring a function:

 TWO_ARG_FUNC max; 

... but you cannot implement the function simply by writing a prototype, for example:

 TWO_ARG_FUNC max { ... // bzzt, error! } 

However, not all is lost. You can force a function to stay true to the prototype with the first direct declaration:

 TWO_ARG_FUNC max; int max(int a, int b) { ... } 

Another option is to resort to C macros:

 #define DEFINE_TWO_ARG_FUNC(funcName) int funcName(int a, int b) DEFINE_TWO_ARG_FUNC(max) { } 

and you can even use a macro to declare a function prototype if you later want to declare a pointer to such a function:

 typedef DEFINE_TWO_ARG_FUNC(TWO_ARG_FUNC); 
+12
source share

Thinking about your post, I’ll talk about what you want to archive. You can try using boost or C ++ 0x lambda. I will go up.

 typedef boost::function<int(int,int)> arithmetic; arithmetic sum = (boost::lambda::_1 + boost::lambda::_2); arithmetic max = boost::lambda::if_then_else_return(boost::lambda::_1 > boost::lambda::_2, boost::lambda::_1, boost::lambda::_2); int j = sum(3,3); // j ist 6 int k = max(4,2); // k is 4 

So maybe this is what you want to archive.

It is also possible with the full feature. Here you go.

 int FullBodyFunction(int i, int j) { return i+j; } arithmetic sum2 = boost::bind(&FullBodyFunction, _1, _2); 

This will do the same as sum1. You can use the whole boost binding file. For example. bind to the method of the object or what you want.

+3
source share

Since, as you say, you can use C ++ 0x, you can do something like this: typedef'ing function :

change , added to your concept for a handler class that contains a callback typedef:

 #include <functional> #include <list> int max(int a, int b) { return (a>=b) ? a : b; } class Handler { public: //typedef int (*Callback)(int, int); typedef std::function<int (int, int)> Callback; void add(Callback func) { functions_.push_back(func); } private: std::list<Callback> functions_; }; int main(int argc, char* argv[]) { Handler handler; handler.add([](int a, int b) -> int { return (a>=b) ? a : b; }); handler.add(max); return 0; } 

This is not the exact syntax you are looking for, but as others have pointed out, it is not possible to directly use typedef to sign a function.

+2
source share

I did not find the exact syntax solution you are looking for, but something like this works:

 #include <cassert> #define arithmetic (int i, int j) -> int #define declare(Func, Name) auto Name Func #define as_ auto sum as_ arithmetic { return i + j; }; declare(arithmetic, max) { return (i>j) ? i : j; }; int main() { assert(sum(2, 4) == 6); assert(max(2, 4) == 4); return 0; } 
+2
source share

All Articles