0

I am attempting to learn C++11 and have started writing a program that reads a textfile into a vector of strings, then passes the vector to a function that will ask the user to select the name of the function they wish to apply to the vector.

I have a function map like so in C++11:

std::map<std::string, void(*)(std::vector<std::string>& v)> funcs
{
    {"f1", f2},
    {"f2", f2},
};

And I call it with the following function:

void call_function(std::vector<std::string>& v)
{
    std::string func;
    std::cout << "Type the name of the function: ";
    std::cin >> func;
    std::cout << "Running function: " << func << "\n";
    funcs[func](v);
}

And two example functions would be:

void f1(std::vector<std::string>& v)
{
    std::cout << "lol1";
}

void f2(std::vector<std::string>& v)
{
    std::cout << "lol2";
}

As of right now, I am successfully able to pass my vector of strings to the functions by calling them from the function map, however, I want to be able to pass a variable number of arguments of varying types. What I want to be able to do is to change my functions to accept integer and string arguments, but not all of my functions will accept the same amount of arguments or arguments of the same type.

For example, I may want to allow one function that is in the map to accept a string and an integer as arguments while another function may only accept a single integer or a single string as the arguments.How can I accomplish this? I've been thus far unable to discover a means of passing variable arguments through map to my functions.

Is this possible with std::map? I was also looking into variadic templates in C++11, but I'm not really understanding them that well.

Can anyone provide any insight?

erm
  • 11
  • 2
  • Can you give us an example of how you want to call them? – David G Oct 22 '13 at 20:44
  • The call_function prompts the user for the name of the function and calls them from there. I assume that when prompted for the name of the function, I can determine which arguments to pass as well, but I need to figure out how to pass different amounts and different types of arguments to the map. Unless you meant something else? I didn't post my full code, I can edit it, if this is not clear. – erm Oct 22 '13 at 20:46

1 Answers1

0

That could be perfectly achieved using variadic templates. For example:

template<typename... ARGS>
struct event
{
   typedef void(*)(ARGS...) handler_type;


   void add_handler(handler_type handler)
   {
        handlers.push_back(handler);
   }

   void raise_event(ARGS args...)
   {
        for(handler_type handler : handlers)
            handler(args...);
   }

private:
    std::vector<handler_type> handlers;
};


void on_foo(int a,int b) { std::cout << "on foo!!! (" << a << "," << b << ")" << std::end; }


int main()
{
    event<int,int> foo;

    foo.add_handler(on_foo);

    foo.raise_event(0,0);
}

This class represents an event. An event is really a set of callbacks of the specified signature (A function of two int parameters, in the example).

Manu343726
  • 13,969
  • 4
  • 40
  • 75
  • I get these errors when I compile that code: testingvar.cpp: In function ‘int main()’: testingvar.cpp:37:27: error: invalid conversion from ‘void (*)(int, int)’ to ‘int’ [-fpermissive] testingvar.cpp:12:9: error: initializing argument 1 of ‘void event::add_handler(int) [with ARGS = {int, int}]’ [-fpermissive] testingvar.cpp:38:9: error: ‘struct event’ has no member named ‘raise_event’ – erm Oct 22 '13 at 21:16