简体   繁体   中英

How to pass a variable number of arguments of varying types to functions in a C++11 function map?

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM