我正在尝试在C ++中创建字符串和方法的映射,但我不知道该怎么做。我想做那样的事情(伪代码):
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);
老实说我不知道C ++是否可行。我想有一个字符串,方法的地图,并能够在我的映射中搜索功能。如果给定的函数字符串名称存在,那么我想用给定的参数调用它。
答案 0 :(得分:17)
好吧,我不是Boost Lovers Club中流行的成员,所以在这里 - 用原始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);
}
}
很明显,如果我已经正确理解你想要一个方法指针,而不是一个函数/静态方法指针。
答案 1 :(得分:6)
由于函数指针,这确实可以在C ++中实现。这是一个简单的例子:
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;
}
}
在处理具有不同返回类型和参数的函数时,这会变得更加棘手。此外,如果要包含非静态成员函数,则应使用Boost.Function
。
答案 2 :(得分:1)
最简单的方法是使用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;
如果您使用成员函数,它会稍微复杂一点 - boost::lambda
可以提供帮助:
#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);
答案 3 :(得分:0)
你当然可以哄骗地图&lt;&gt;容器将字符串映射到函数指针。但这是一种非常难以做到的事情。
创建所有函数名称的枚举。将字符串名称映射到枚举值。然后使用switch语句根据枚举值调用函数。你会因为变灰而节省很多头发。
答案 4 :(得分:0)
见this question。 method
最方便的表示法是function<signature>
,其中function
包含在 boost 中或{C} 0x下的<utility>
中。
在您的情况下,签名就是这样。
map<string, function<double (double)> map; ...
map["sin"](1.0);
答案 5 :(得分:0)
我认为这可行,假设您的函数返回int
并且只需要一个int
参数:
map<string, int(*func)(int)>
如果函数参数类型或返回值不同,我认为你不能这样做。
答案 6 :(得分:0)
//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);