Reputation: 3802
Is it possible to store pointers to various heterogenous functions like:
In the header:
int functionA (int param1);
void functionB (void);
Basically this would the part I don't know how to write:
typedef ??boost::function<void(void)>?? functionPointer;
And afterwards:
map<char*,functionPointer> _myMap;
In the .cpp
void CreateFunctionMap()
{
_myMap["functionA"] = &functionA;
_myMap["functionB"] = &functionB;
...
}
And then reuse it like:
void execute(int argc, char* argv[])
{
if(argc>1){
int param = atoi(argv[1]);
int answer;
functionPointer mfp;
mfp = map[argv[0]];
answer = *mfp(param);
}
else{
*map[argv[0]];
}
}
etc.
Thanks
--EDIT--
Just to give more info:
The reason for this question is that I am implementing a drop-down "quake-style" console for an already existing application. This way I can provide runtime command line user input to access various already coded functions of various types i.e.:
/exec <functionName> <param1> <param2> ...
Upvotes: 2
Views: 1698
Reputation: 56956
You can use
boost::variant<
boost::function<void(void)>,
boost::function<void(int)> >
Upvotes: 3
Reputation: 9172
If you want to have "pointer to something, but I'm not going to define what, and it could be a variety of things anyway" you can use void *
.
But you really shouldn't.
void *
is purely a pointer. In order to do anything with it, you have to cast it to a more meaningful pointer, but at that point, you've lost all type safety. What's to stop someone from using the wrong function signature? Or using a pointer to a struct?
EDIT
To give you a more useful answer, there's no need to put this all into a single map. It's ok to use multiple maps. I.e.
typedef boost::function<void(void)> voidFunctionPointer;
typedef boost::function<int(int)> intFunctionPointer;
map<std::string, voidFunctionPointer> _myVoidMap;
map<std::string, intFunctionPointer > _myIntMap;
void CreateFunctionMap()
{
_myVoidMap["functionA"] = &functionA;
_myIntMap["functionB"] = &functionB;
...
}
void execute(int argc, char* argv[])
{
if(argc>1){
int param = atoi(argv[1]);
int answer;
// todo: check that argv[0] is actually in the map
intFunctionPointer mfp = _myIntMap[argv[0]];
answer = mfp(param);
}
else{
// todo: check that argv[0] is actually in the map
voidFunctionPointer mfp = _myVoidMap[argv[0]];
mfp();
}
}
Upvotes: 3
Reputation: 81349
Each of your functions has a different type, so you need some kind of type erasure. You could use the most generic of them: Boost.Any. You can have a map
of boost::any
, but you need to know the type of the function in order to get it back and call it.
Alternatively, if you know your arguments ahead of time you can bind
them with the function call and have all functions in the map be nullary functions: function< void() >
. Even if you don't, you may be able to get away with it by binding the argument to references, and then at call time fill the referred variables with the appropiate arguments.
Upvotes: 1
Reputation: 7705
Can you not use the command pattern to encapsulate the function calls. So you can store the functions in functors and call them after wards. For functor implementation you can have a look at Modern C++ Design by Andrei Alexandrescu.
Upvotes: 2
Reputation: 13907
Why not just add functions of type int (*func)(int argc, char* argv[])
? You could easily remove first arg from execute
's params and call the relevant one.
Upvotes: 2