C++如何把一个字符串识别为函数

如题所述

#include <iostream>
#include <map>
#include <string>

int use_foo1_1(int n)
{
return n;
}

int use_foo1_2(int n)
{
return n - 1;
}

int use_foo2_1(int n, int m)
{
return n + m;
}

int use_foo2_2(int n, int m)
{
return n * m;
}

void test1(void)
{
typedef int (*foo_type)(int); //函数类型由函数返回值类型和参数列表类型决定
typedef std::map<std::string, foo_type> foo_map_type;

foo_map_type map;
map["aaa"] = use_foo1_1;
map["bbb"] = use_foo1_2;

std::cout << (*map["aaa"])(10) << std::endl;
std::cout << (*map["bbb"])(10) << std::endl;

}

//由于 map的value部分只能接受一种类型
// use_foo1_1 和 use_foo2_1 不是同一种类型的函数
//所以 保存函数的指针 使用 void* 这样就能存储了,
// 但是通过函数指针调用函数的时候需要把 void* 转换成相对应的指针类型才行
//所以 一个map结点需要保存2个内容 函数指针和 转换函数的类型说明符号

void test2(void)
{
typedef int (*foo1_type)(int); //函数类型由函数返回值类型和参数列表类型决定
typedef int (*foo2_type)(int, int);

typedef std::map<std::string, std::pair<void*, int> > foo_map_type;

foo_map_type map;
map["aaa"] = std::pair<void*, int>(use_foo1_1, 1);
map["bbb"] = std::pair<void*, int>(use_foo2_1, 2);

if(map["aaa"].second == 1)
{
std::cout << (*reinterpret_cast<foo1_type>(map["aaa"].first))(10) << std::endl;
}

if(map["aaa"].second == 2)
{
std::cout << (*reinterpret_cast<foo2_type>(map["aaa"].first))(10, 20) << std::endl;
}

if(map["bbb"].second == 1)
{
std::cout << (*reinterpret_cast<foo1_type>(map["bbb"].first))(10) << std::endl;
}

if(map["bbb"].second == 2)
{
std::cout << (*reinterpret_cast<foo2_type>(map["bbb"].first))(10, 20) << std::endl;
}
}

//然后一个更通用的模式

// 要通用 就会碰到 3个问题,boost里有现成的解决方案 当然你也可以自己想办法
// 1 函数指针类型 // 用boost::bind 存储
// 2 函数参数表类型 // 统一成boost::tuple 传递时用boost::any
// 3 函数返回值类型 // 统一成参数返回

#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/any.hpp>
#include <boost/tuple/tuple.hpp>

#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>

class foo_container
{
private:
class base_foo_handler // 为了能够统一存储 使用 接口模式 做存储规范
{
public:
virtual void call(const boost::any& params) const = 0;
};

template<typename Handler_Foo, typename Handler_Params_Parse_And_Call, typename Handler_Ret_Back>
class foo_handler
: public base_foo_handler //带返回值的函数包装
{
public:
typedef Handler_Foo foo_type;
typedef Handler_Params_Parse_And_Call param_parse_and_call_type;
typedef Handler_Ret_Back ret_back_type;

foo_handler(const foo_type& foo, const param_parse_and_call_type& params_parse, const ret_back_type& ret_back)
: _foo(foo), _params_parse_and_call(params_parse), _ret_back(ret_back)
{
}

virtual void call(const boost::any& params) const
{
_params_parse_and_call(_foo, params, _ret_back);
}

private:
foo_type _foo;
param_parse_and_call_type _params_parse_and_call;
ret_back_type _ret_back;
};

template<typename Handler_Foo, typename Handler_Params_Parse_And_Call>
class foo_handler<Handler_Foo, Handler_Params_Parse_And_Call, void>
: public base_foo_handler //不带返回值的函数包装
{
public:
typedef Handler_Foo foo_type;
typedef Handler_Params_Parse_And_Call param_parse_and_call_type;
typedef void ret_back_type;

foo_handler(const foo_type& foo, const param_parse_and_call_type& params_parse)
: _foo(foo), _params_parse_and_call(params_parse)
{
}

virtual void call(const boost::any& params) const
{
_params_parse_and_call(_foo, params);
}

private:
foo_type _foo;
param_parse_and_call_type _params_parse_and_call;
};

template<std::size_t>
struct params_foo_switch //函数执行的规范函数
{
template<typename Handler_Foo, typename Tuple>
static void s_params_parse_and_call(const Handler_Foo& foo, const boost::any& params) // 不带返回值 //参数有多少个就补充多少组
{
BOOST_MPL_ASSERT((boost::mpl::bool_<false>));
}

template<typename Handler_Foo, typename Tuple, typename Handler_Ret_Back>
static void s_params_parse_and_call(const Handler_Foo& foo, const boost::any& params, const Handler_Ret_Back& ret) //带返回值 //参数有多少个就补充多少组
{
BOOST_MPL_ASSERT((boost::mpl::bool_<false>)); // 这只是个函数的说明 实际用的是特例函数
}
};

template<>
struct params_foo_switch<1> //函数执行的规范函数(1参数)
{
template<typename Handler_Foo, typename Tuple>
static void s_params_parse_and_call(const Handler_Foo& foo, const boost::any& params)
{
typedef Tuple tuple_type;
const tuple_type& tuple = boost::any_cast<const tuple_type&>(params);
foo(boost::get<0>(tuple));
}

template<typename Handler_Foo, typename Tuple, typename Handler_Ret_Back>
static void s_params_parse_and_call(const Handler_Foo& foo, const boost::any& params, const Handler_Ret_Back& ret)
{
typedef Tuple tuple_type;
const tuple_type& tuple = boost::any_cast<const tuple_type&>(params);
ret(foo(boost::get<0>(tuple)));
}
};

template<>
struct params_foo_switch<2> //函数执行的规范函数(2参数)
{
template<typename Handler_Foo, typename Tuple>
static void s_params_parse_and_call(const Handler_Foo& foo, const boost::any& params)
{
typedef Tuple tuple_type;
const tuple_type& tuple = boost::any_cast<const tuple_type&>(params);
foo(boost::get<0>(tuple), boost::get<1>(tuple));
}

template<typename Handler_Foo, typename Tuple, typename Handler_Ret_Back>
static void s_params_parse_and_call(const Handler_Foo& foo, const boost::any& params, const Handler_Ret_Back& ret)
{
typedef Tuple tuple_type;
const tuple_type& tuple = boost::any_cast<const tuple_type&>(params);
ret(foo(boost::get<0>(tuple), boost::get<1>(tuple)));
}
};

template<>
struct params_foo_switch<3> //函数执行的规范函数(3参数)
{
template<typename Handler_Foo, typename Tuple, size_t>
static void s_params_parse_and_call(const Handler_Foo& foo, const boost::any& params) // 不带返回值
{
typedef Tuple tuple_type;
const tuple_type& tuple = boost::any_cast<const tuple_type&>(params);
foo(boost::get<0>(tuple), boost::get<1>(tuple), boost::get<2>(tuple));
}

template<typename Handler_Foo, typename Tuple, typename Handler_Ret_Back>
static void s_params_parse_and_call(const Handler_Foo& foo, const boost::any& params, const Handler_Ret_Back& ret)
{
typedef Tuple tuple_type;
const tuple_type& tuple = boost::any_cast<const tuple_type&>(params);
ret(foo(boost::get<0>(tuple), boost::get<1>(tuple), boost::get<2>(tuple)));
}
};

//如要处理4参以上的函数 请自己补充, 一般20参 足够了copy pase的体力活

typedef boost::shared_ptr<base_foo_handler> foo_handler_ptr_type;
typedef std::map<std::string, foo_handler_ptr_type> map_type;
typedef map_type::const_iterator map_citer_type;

private:
typedef foo_container this_type;

public:

foo_container(void){}
~foo_container(void){}

template<typename Tuple, typename Handler_Foo>
bool register_foo(const std::string& name, const Handler_Foo& foo)
{
typedef Handler_Foo foo_type;
typedef Tuple tuple_type;

return prv_register_foo<foo_type>(name, foo,
boost::bind(¶ms_foo_switch< boost::tuples::length<tuple_type>::value>::s_params_parse_and_call
<foo_type, tuple_type>,
_1, _2));

}

template<typename Tuple, typename Handler_Foo, typename Handler_Ret_Back>
bool register_foo(const std::string& name, const Handler_Foo& foo, const Handler_Ret_Back& ret)
{
typedef Handler_Foo foo_type;
typedef Handler_Ret_Back ret_back_type;
typedef Tuple tuple_type;

return prv_register_foo<foo_type, ret_back_type>(name, foo, ret,
boost::bind(¶ms_foo_switch< boost::tuples::length<tuple_type>::value>
::s_params_parse_and_call<foo_type, tuple_type, ret_back_type>,
_1, _2, _3));

}

template<typename Tuple>
bool call(const std::string& name, const Tuple& params) const
{
map_citer_type iter = _map.find(name);
if(iter == _map.end())
{
return false;
}

iter->second->call(boost::any(params));
return true;
}

private:

template<typename Handler_Foo, typename Handler_Params_Parse_And_Call>
bool prv_register_foo(const std::string& name, const Handler_Foo& foo, const Handler_Params_Parse_And_Call params)
{
typedef foo_handler<Handler_Foo, Handler_Params_Parse_And_Call, void> now_foo_handler_type;
foo_handler_ptr_type ptr(new now_foo_handler_type(foo, params));
return _map.insert(map_type::value_type(name, ptr)).second;
}

template<typename Handler_Foo, typename Handler_Ret_Back, typename Handler_Params_Parse_And_Call>
bool prv_register_foo(const std::string& name, const Handler_Foo& foo, const Handler_Ret_Back& ret,
const Handler_Params_Parse_And_Call& params)
{
typedef foo_handler<Handler_Foo, Handler_Params_Parse_And_Call, Handler_Ret_Back> now_foo_handler_type;

foo_handler_ptr_type ptr(new now_foo_handler_type(foo, params, ret));
return _map.insert(map_type::value_type(name, ptr)).second;
}

private:
map_type _map;
};

template<typename T>
void back_ret(const T& val)
{
std::cout << val << std::endl;
}

void test3(void)
{
foo_container cont;
cont.register_foo< boost::tuple<int> >("aaa", boost::bind(&use_foo1_1, _1), boost::bind(&(back_ret<int>), _1));
cont.register_foo<boost::tuple<int, int> >("bbb", boost::bind(&use_foo2_1, _1, _2), boost::bind(&back_ret<int>, _1));

cont.call("aaa", boost::make_tuple(10));
cont.call("bbb", boost::make_tuple(10, 20));

}

int main(int argc, char* argv[])
{
test1();
test2();

test3();

char cc = 0;
std::cin >> cc;
return 0;
}

vc2010下编译运行通过 功能扩充 弄清楚后你自己添加
boost版本1.53
温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-07-30
你的意思是直接写一个字符串,然后变成一个函数吗?你可以使用创建模式,通过工厂加工,又或者使用其他的方法,我觉得你表达不是很清晰追问

对,,,比如输入"sin(x)*cos(x)",,,然后我用它在程序中变成f(x)=sin(x)*cos(x)

追答

这个你可以自己写一个函数来比较呀,比如可以这么写

if (0 == strcmp("sin(x)*cos(x)", strParam))
{
return (sin(x)*cos(x));//strParam为传进来的字符串参数
}

或者你可以把这个写成一宏如下
#define F(x) (sin(x)*cos(x))
调用的时候直接这么调用就可以了
double dTemp = F(x)。

注意的是:在C++/C中都是用弧度来计算,因此首先应该将角度转换成弧度。

第2个回答  2013-07-30
.... 这个你自己写接口吧,if 或者case switch追问

我要用到各种函数,而且涉及分词,感觉好麻烦

相似回答