I am looking for a way to call different functions by a string input.
I have a map that ties each unique string to a function pointer and a lookup function to search the map and return a pointer if found.
Now the trick is, I need a way to store and return pointers to functions with at least different return types, if possible, also with different signatures.
The usage would be:
Get a string input from a network socket -> find and execute the found function -> shove the result straight back into the socket to be serialized and sent, not caring what actually happened.
Is this doable? If not, how would one approach this task?
While you can't store different function pointers, you can store objects which contain those functions.
I think the edited part makes it clearer? This code can be optimized a little. Play around with it.
No, it's really not doable, you need a real interpreted language if you want to do something like this. As soon as the signature is not constant then you need something a lot more involved.
Can't you use specialization and templates to work around the issue?
How about making all those functions have the same signature? You could make all return types implement an interface, or use a collection, class, union or struct. Same for the arguments.
This is doable in C++11 with Variadic Templates. Check my answer at https://stackoverflow.com/a/33837343/1496826
That can be done with a bit of boilerplate code in different ways. If the number of signatures is small enough you can hold multiple vectors of function pointers (one per function type) and then a map that maps the function name with a type identifier (used to select the vector) and the position within the vector.
The second option would be to store a
boost::variant
(again, if the set of signatures is small). You would need to provide a visitor object that evaluates the function (for each function type stored) and yields the result. The type is managed by theboost::variant
type so there would be no need for the type tag to be stored in the map.You can also use full type erasure and store in the map a tag determining the type of function to be called and a
boost::any
object storing the function pointer. You can use the type information to retrieve the pointer and execute the function, but you will have to manually handle theswitch
based on function type.The simplest approach, on the other hand, is to write adapters that have a fixed interface. Then just store the pointers to the adapters in the map.