I\'m trying to create a map of string and method in C++, but I don\'t know how to do it. I would like to do something like that (pseudocode):
map
//pick one
typedef float (*func_type_1)(float);
typedef boost::function<float(float)> func_type_2;
std::map<std::string,func_type> fm;
fm["sin"] = &Math::sin;
fm["cos"] = &Math::cos;
auto f = fm[str];
result = f(42);
I think this would work, assuming your function returns int
and takes a single int
parameter:
map<string, int(*func)(int)>
If the function parameter types or return values differ, I don't think you could do this though.
You can certainly coax the map<> container to map strings to function pointers. But that is a really hard way of doing something fairly simple.
Create an enum of all the function names. Map the string names to the enum values. Then use a switch statement to call the functions based on the enum value. You'll save a lot of hair from turning grey.
Well, I'm not a member of the popular here Boost Lovers Club, so here it goes - in raw C++.
#include <map>
#include <string>
struct Math
{
double sinFunc(double x) { return 0.33; };
double cosFunc(double x) { return 0.66; };
};
typedef double (Math::*math_method_t)(double);
typedef std::map<std::string, math_method_t> math_func_map_t;
int main()
{
math_func_map_t mapping;
mapping["sin"] = &Math::sinFunc;
mapping["cos"] = &Math::cosFunc;
std::string function = std::string("sin");
math_func_map_t::iterator x = mapping.find(function);
int result = 0;
if (x != mapping.end()) {
Math m;
result = (m.*(x->second))(20);
}
}
That's obviously if I have understood correctly that you want a method pointer, not a function/static method pointer.
See this question. The most convenient notation for method
is function<signature>
where function
is either included in boost or in <utility>
under C++0x.
In your case, the signature would be like this.
map<string, function<double (double)> map; ...
map["sin"](1.0);
The easiest way would be to use boost::function:
#include <map>
#include <string>
#include <boost/function.hpp>
using namespace std;
// later...
map<string, boost::function<double(double)> > funcs;
funcs["sin"] = &Math::sinFunc;
It gets slightly more complex if you're using member functions - boost::lambda can help:
#include <map>
#include <string>
#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
using namespace std;
namespace l = boost::lambda;
// later...
Math *m = new Math();
map<string, boost::function<double(double)> > funcs;
funcs["sin"] = l::bind(&Math::sinFunc, m, l::_1);