areuz areuz - 2 years ago 132
C++ Question

Calling functions from a std::map

I'm trying to construct

that will serve as a handler for my functions. To explain why, I'll use this to scan for user input, check the map for a match. If a match is found, I will call the function and copy the rest of the user-inputted line to the function;

class Object
Object(std::map<std::string, void(*)(const std::string&)> MAP)

Quick example code:

class Main
void testFunc(const std::string& A)


void construct()
std::map<std::string, void(*)(const std::string&)> {
{"exit", [](const std::string &A){ exit(1); }},
//{"test1", (void(Main::*)(const std::string&))&testFunc},
//{"test2", [](const std::string &A){ testFunc(A); }},
//{"test3", [this](const std::string &A){ testFunc(A); }},

Neither of the commented lines worked, creating different errors, but the other lines succeeded and there are no runtime errors (Well, NULL would be, but I'm handling that).

My question is, Am I imagining the mechanics of this properly, if not, should I save just the pointers and cast to functions later? Is it possible to save a reference and call functions inside a object that is defined only inside the class scope (calls would be made from inside the class too)?

A lot of questions.. I know. But I've never seen this done like this before.. so I guess there might be a good reason.

Because I didn't specify the errors, here is a link;

Answer Source

Non-static member functions are different from non-member functions in that they take an extra implicit argument - the class instance. Main::testFunc requires two arguments: a Main and a std::string const&. But your interface only allows for a single argument. The only way to make this work is to create a global Main* that the function would reference - which is a terribly brittle design.

Instead, you could make your interface more generic by using std::function<void(std::string const&)>. This is any callable that takes a std::string const&, instead of just a pointer to a function. This would allow you to write your last version:

{"test3", [this](const std::string &A){ testFunc(A); }},

and is probably your best bet.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download