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

Cha*_*les 4 c++ boost

Boost带有一个示例文件

boost_1_41_0\libs\function_types\example

interpreter.hppinterpreter_example.hpp

我试图创建一种情况,我有一堆不同的参数,返回类型等函数所有寄存器并记录到一个位置.然后有能力拉出一个函数并用一些参数执行它.

在这里阅读了几个问题之后,从其他几个问题来看,我认为在这个示例文件中实现的设计与我能够获得的一样好.它需要任何类型的函数,并允许您使用字符串参数列表调用它,该列表被解析为正确的数据类型.基本上它是一个控制台命令解释器,这可能是它的意思.

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

在示例中,您将看到

interpreter.register_function("echo", & echo);
interpreter.register_function("add", & add);
interpreter.register_function("repeat", & repeat);
Run Code Online (Sandbox Code Playgroud)

我想做点什么

test x;
interpreter.register_function("classFunc", boost::bind( &test::classFunc, &x ) );
Run Code Online (Sandbox Code Playgroud)

但这打破了任意数量的论点特征.所以我在想某种自动生成boost :: bind(&test :: classFunc,&x,_1,_2,_3 ......)就是票,我只是不确定实现它的最佳方法.

谢谢

Ale*_*mps 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);
Run Code Online (Sandbox Code Playgroud)

enable_if语句用于防止在编译时使用错误的方法.现在,您需要了解的内容:

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

因此,需要做的只是在"解析"应用中添加一步,即将相关对象添加到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());
}
Run Code Online (Sandbox Code Playgroud)

在interpreter :: 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) );      
}
Run Code Online (Sandbox Code Playgroud)

这样,它将简单地跳过第一个参数类型并正确解析所有内容.该方法可以这样调用:invoker.register_function("SomeMethod",&TheClass::TheMethod,&my_object);