typedef std::string (*function_pointer0)();
typedef std::string (*function_pointer1)(const std::string &);
typedef std::string (*function_pointer2)(const std::string &, const std::string &);
//etc.
std::map<std::string, function_pointer0> function_map0;
std::map<std::string, function_pointer1> function_map1;
std::map<std::string, function_pointer2> function_map2;
//etc.
//...
//Note: you can't put these blocks in a loop because the types are heterogeneous.
if (args.size() == 0){
auto it = function_map0.find(command);
if (it == function_map0.end())
//not found
return (*it)();
}
if (args.size() == 1){
auto it = function_map1.find(command);
if (it == function_map1.end())
//not found
return (*it)(args[0]);
}
if (args.size() == 2){
auto it = function_map2.find(command);
if (it == function_map2.end())
//not found
return (*it)(args[0], args[1]);
}
//etc.
You can pack your n < max_args arguments into a tuple of max_args elements. You could use a "null" type to fill the rest of the elements of the tuple. You should be able to call a function with only the first n elements of that tuple.
I'm away from my compiler right now, but I'll see if I can hack some code together when I get back home.