问题
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<string, method> mapping =
{
"sin", Math::sinFunc,
"cos", Math::cosFunc,
...
};
...
string &function;
handler = mapping.find(function);
int result;
if (handler != NULL)
result = (int) handler(20);
To be honest I don't know is it possible in C++. I would like to have a map of string, method and be able to search for function in my mapping. If given string name of function exists then I would like to call it with given param.
回答1:
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.
回答2:
This is indeed possible in C++, thanks to function pointers. Here's a simple example:
std::string foo() { return "Foo"; }
std::string bar() { return "Bar"; }
int main()
{
std::map<std::string, std::string (*)()> m;
// Map the functions to the names
m["foo"] = &foo;
m["bar"] = &bar;
// Display all of the mapped functions
std::map<std::string, std::string (*)()>::const_iterator it = m.begin();
std::map<std::string, std::string (*)()>::const_iterator end = m.end();
while ( it != end ) {
std::cout<< it->first <<"\t\""
<< (it->second)() <<"\"\n";
++it;
}
}
This gets more tricky when dealing with functions with different return types and arguments. Also, if you are including non-static member functions, you should use Boost.Function
.
回答3:
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);
回答4:
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);
回答5:
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.
回答6:
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.
回答7:
//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);
来源:https://stackoverflow.com/questions/3113139/how-to-create-mapstring-classmethod-in-c-and-be-able-to-search-for-functi