C ++ std :: map of heterogeneous function pointers
Is it possible to store pointers to various heterogeneous functions such as:
In the title:
int functionA (int param1);
void functionB (void);
Basically this will be the part that I don't know how to write:
typedef ??boost::function<void(void)>?? functionPointer;
And than:
map<char*,functionPointer> _myMap;
In .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]];
}
}
and etc.
thank
- EDIT -
Just to find out more:
The reason for this question is because I am implementing a "quake-style" dropdown console for an existing application. This way I can provide user command line input at runtime to access various already coded functions of various types. Ie:
/exec <functionName> <param1> <param2> ...
source to share
Each of your functions is of a different type, so you need some type erasure. You can use the most common ones: Boost.Any. You can have map
from boost::any
, but you need to know the type of the function in order to return and call it.
Alternatively, if you know in advance their arguments, you can bind
cause them function call and have all the features on the map - it's zero functions function< void() >
. Even if you don't, you can get away with it by binding the argument to references and then, during the call, fill the specified variables with the appropriate arguments.
source to share
If you want to have a "pointer to something, but I won't define what, and it could be a lot of things anyway", you can use void *
.
But you really shouldn't.
void *
is purely a pointer. To do anything about it, you have to apply it to a more meaningful pointer, but at this point you lost all type safety. What is stopping someone from using the wrong signature? Or using a pointer to a struct?
EDIT
To give you a more useful answer, there is no need to stick it all into one card. It is good to use multiple cards. 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();
}
}
source to share