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> ...

      

+2


source to share


5 answers


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.

+1


source


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();
  }
}

      

+3


source


you can use

boost::variant<
    boost::function<void(void)>,
    boost::function<void(int)> >

      

+3


source


Why not just add type functions int (*func)(int argc, char* argv[])

? You can easily remove the first arg from the parameters execute

and call the appropriate one.

+2


source


You cannot use a command template to encapsulate function calls. This way you can store functions in functors and call them after the trustees. For a functor implementation, you can take a look at Modern C ++ Design by Andrei Alexandrescu.

+2


source







All Articles