1

I'm trying to make a class that can hold and later call functions. It stores the functions in a map along with a string that holds the name of the function.

I tried doing this on Linux with GCC and got the following error: "invalid conversion from void(*)() to void *" on the line functionsMap[nameOfFunction] = func;

Here's the entire program I have so far. It's not done yet, but I'm really curious as to why this would compile under Visual C++ and not GCC. If I'm doing something wrong or could be doing something better, please let me know. Thanks!

#include <iostream>
#include <map>
#include <string>
using namespace std; 

class Dyn_Class{
private: 
    map<string, void *> functionsMap; 

public: 
    Dyn_Class(){} 

    template<typename ReturnValue>
    void add_func( string nameOfFunction, ReturnValue(*func)() ){
        functionsMap[nameOfFunction] = func; 
    }

    void remove_func( string nameOfFunction ){

    }

    Dyn_Class operator()(string nameOfFunction){

    }
}; 

void print(void){
    for(int index = 0; index < 9; index++){
        cout << index << "   "; 
    }
    cout << endl; 
}

int main(){
    Dyn_Class functionsList; 

    functionsList.add_func("print", print); 

    return 0; 
}
Cuthbert
  • 2,908
  • 5
  • 33
  • 60

3 Answers3

2

To have a map of pointers to function taking no arguments and returning void you need:

std::map<std::string, void(*)()> functionsMap; 

There is no point making add_func a template as it will only work when instantiated with ReturnValue = void (unless you add a potentially unsafe cast to its implementation).

If your code compiles with Visual C++ it is because Visual C++ is being permissive.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • What if I wanted the map to be able to take a function with a variable number of arguments and overloaded add_func to accept functions that did have arguments? – Cuthbert May 14 '12 at 20:54
  • @d2jxp: You can't do that with function pointers because the function signature is part of the type of the function pointer. How would you call any of your functions correctly when you retrieved them from the map? – CB Bailey May 14 '12 at 20:58
0

You can pass that function as a parameter like this:

void add(void * f()){...}

How do you pass a function as a parameter in C?

Community
  • 1
  • 1
teo236
  • 11
0

Think on using std::function instead:

class Dyn_Class{
private: 
    map<string, function<void()> > functionsMap; 

public: 
    Dyn_Class(){} 

    template<typename FUNC>
    void add_func(const string& nameOfFunction, FUNC func){
        functionsMap.insert(make_pair(nameOfFunction, func));
    }

    void remove_func(const string& nameOfFunction ){

    }

    void operator()(const string& nameOfFunction){
        functionsMap[nameOfFunction]();
    }
}; 

Benefits? Using "function", you could use your plain old function pointers, you can use functors or you can use lambda expressions instead:

DynClass dyn;
dyn.add("print", []() { printf("Say hi"; } );
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
oopscene
  • 33
  • 3