首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Boost类成员函数的Interpreter.hpp示例

Boost类成员函数的Interpreter.hpp示例
EN

Stack Overflow用户
提问于 2009-12-05 06:15:25
回答 3查看 1K关注 0票数 4

Boost中有一个示例文件

boost_1_41_0\libs\function_types\example

名为interpreter.hppinterpreter_example.hpp

我试图创建一种情况,在这种情况下,我有许多不同的参数、返回类型等函数,这些函数都是注册的,并被记录到一个位置。然后有能力提取一个函数,并使用一些参数来执行它。

在这里阅读了几个问题之后,我认为在这个示例文件中实现的设计是我所能得到的最好的设计。它接受任何类型的函数,并允许您使用字符串参数列表调用它,该列表被解析为正确的数据类型。基本上它是一个控制台命令解释器,这可能就是它所要说明的。

我一直在研究代码,试图获得相同的实现来接受类成员函数,但到目前为止都没有成功。我想知道是否有人可以建议所需的修改,或者可能做一些类似的工作,并有一些相同的代码。

在这个例子中,您将看到

代码语言:javascript
复制
interpreter.register_function("echo", & echo);
interpreter.register_function("add", & add);
interpreter.register_function("repeat", & repeat);

我想做这样的事

代码语言:javascript
复制
test x;
interpreter.register_function("classFunc", boost::bind( &test::classFunc, &x ) );

但这破坏了任意数量的参数特性。因此,我正在考虑某种自动生成boost::bind( &test::classFunc,&x,_1,_2,_3 .)会是罚单,我只是不确定实现它的最佳方法。

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-08-03 15:28:48

我一直在处理这个问题,并且在某种程度上成功地使boost解释器接受了成员函数,例如:

代码语言:javascript
复制
// 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语句用于防止在编译时使用错误的方法。现在,你需要了解的是:

  • 它使用boost::mpl解析可调用内置的参数类型(基本上是一个函数指针)。
  • 然后,在编译时准备一个融合向量(它可以同时存储不同类型的不同对象)。
  • 当mpl完成对每个参数的解析时,“解析”apply方法将在模板后面的"invoke“apply方法中分叉。
  • 主要问题是成员可调用内置的第一个参数是持有被调用的方法.的对象。
  • 据我所知,mpl不能解析除了可调用的内建(例如:Bind结果)以外的其他东西的参数。

因此,只需向“解析”应用添加一个步骤,即将相关对象添加到apply循环中!下面是:

代码语言:javascript
复制
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());
}

口译员::

代码语言:javascript
复制
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);

票数 7
EN

Stack Overflow用户

发布于 2009-12-05 09:29:14

我不喜欢融合,因此不知道如何以简单而优雅的方式修复它(我主要不知道成员函数应该如何工作),但我研究的类似的东西可能是您的另一种选择。

如果要查看结果,它位于火呼吸存储库中。

简言之:

  • MethodConverter.h包含主要功能
  • 丑陋的gen.py生成那个头。
  • ConverterUtils.h包含实用程序功能,比如转换到目标类型。
  • TestJSAPIAuto.htest.h包含一个单元测试,它显示了它的工作状态。

主要的更改可能涉及剥离特定于FB的类型,在调用函子之前对输入序列进行标记,并提供您自己的转换函数。

票数 1
EN

Stack Overflow用户

发布于 2009-12-05 06:44:40

一个选择是创建一组模板。

代码语言:javascript
复制
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生成所需的模板数量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1851315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档