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 ......)就是票,我只是不确定实现它的最佳方法
由于
答案 0 :(得分:7)
我一直在研究这个问题,并且我已经成功地使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());
}
解释器中的:: invoker
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);
答案 1 :(得分:1)
我没有进入融合,因此没有看到如何以简单而优雅的方式解决它(我主要看不到成员函数应该如何工作),但我在something similar上工作过可能是你的另一种选择 如果您想查看结果,请将其放在Firebreath存储库中。
简而言之:
主要更改可能涉及剥离特定于FB的类型,在调用仿函数之前对输入序列进行标记,并提供自己的转换函数。
答案 2 :(得分:0)
一个选项是制作一组模板
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生成所需数量的模板