Boost中有一个示例文件
boost_1_41_0\libs\function_types\example
名为interpreter.hpp和interpreter_example.hpp
我试图创建一种情况,在这种情况下,我有许多不同的参数、返回类型等函数,这些函数都是注册的,并被记录到一个位置。然后有能力提取一个函数,并使用一些参数来执行它。
在这里阅读了几个问题之后,我认为在这个示例文件中实现的设计是我所能得到的最好的设计。它接受任何类型的函数,并允许您使用字符串参数列表调用它,该列表被解析为正确的数据类型。基本上它是一个控制台命令解释器,这可能就是它所要说明的。
我一直在研究代码,试图获得相同的实现来接受类成员函数,但到目前为止都没有成功。我想知道是否有人可以建议所需的修改,或者可能做一些类似的工作,并有一些相同的代码。
在这个例子中,您将看到
interpreter.register_function("echo", & echo);
interpreter.register_function("add", & add);
interpreter.register_function("repeat", & repeat);我想做这样的事
test x;
interpreter.register_function("classFunc", boost::bind( &test::classFunc, &x ) );但这破坏了任意数量的参数特性。因此,我正在考虑某种自动生成boost::bind( &test::classFunc,&x,_1,_2,_3 .)会是罚单,我只是不确定实现它的最佳方法。
谢谢
发布于 2010-08-03 15:28:48
我一直在处理这个问题,并且在某种程度上成功地使boost解释器接受了成员函数,例如:
// Registers a function with the interpreter,
// will not compile if it's a member function.
template<typename Function>
typename boost::enable_if< ft::is_nonmember_callable_builtin<Function> >::type
register_function(std::string const& name, Function f);
// Registers a member function with the interpreter.
// Will not compile if it's a non-member function.
template<typename Function, typename TheClass>
typename boost::enable_if< ft::is_member_function_pointer<Function> >::type
register_function(std::string const& name, Function f, TheClass* theclass);enable_if语句用于防止在编译时使用错误的方法。现在,你需要了解的是:
因此,只需向“解析”应用添加一个步骤,即将相关对象添加到apply循环中!下面是:
template<typename Function, typename ClassT>
typename boost::enable_if< ft::is_member_function_pointer<Function> >::type
interpreter::register_function( std::string const& name,
Function f,
ClassT* theclass);
{
typedef invoker<Function> invoker;
// instantiate and store the invoker by name
map_invokers[name]
= boost::bind(&invoker::template apply_object<fusion::nil,ClassT>
,f,theclass,_1,fusion::nil());
}口译员::
template<typename Args, typename TheClass>
static inline
void
apply_object( Function func,
TheClass* theclass,
parameters_parser & parser,
Args const & args)
{
typedef typename mpl::next<From>::type next_iter_type;
typedef interpreter::invoker<Function, next_iter_type, To> invoker;
invoker::apply( func, parser, fusion::push_back(args, theclass) );
}这样,它将简单地跳过第一个参数类型并正确地解析所有内容。这个方法可以这样调用:invoker.register_function("SomeMethod",&TheClass::TheMethod,&my_object);
发布于 2009-12-05 09:29:14
我不喜欢融合,因此不知道如何以简单而优雅的方式修复它(我主要不知道成员函数应该如何工作),但我研究的类似的东西可能是您的另一种选择。
如果要查看结果,它位于火呼吸存储库中。
简言之:
主要的更改可能涉及剥离特定于FB的类型,在调用函子之前对输入序列进行标记,并提供您自己的转换函数。
发布于 2009-12-05 06:44:40
一个选择是创建一组模板。
template <class T, class Ret>
void register_function(const char *name, Ret (T::*fn)()) { /* boost::bind or your way to register here */ }
template <class T, class Ret, class Arg1>
void register_function(const char *name, Ret (T::*fn)(Arg1)) { /*...*/ )以此类推。在C++0x附带了它的各种模板之前,您可以使用Boost.Preprocessor生成所需的模板数量。
https://stackoverflow.com/questions/1851315
复制相似问题