1

我正在使用 Boost Spirit 解析器,当解析器正在解析时,语义动作会反映到 ParserActions 类的实例中。

这是解析器的代码(相关部分)

struct urdf_grammar : public grammar<urdf_grammar> {

template <typename ScannerT>
        struct definition {

    definition(urdf_grammar const& self) {


        prog = (alpha_p >> *alnum_p)[&(self.actions.do_prog)];

    }

    rule<ScannerT> prog;

    rule<ScannerT> const&
            start() const {
        return prog;
    }
};

const ParserActions & actions;

explicit urdf_grammar(const ParserActions & actions = ParserActions()) : actions(actions) {
}  
};
4

3 回答 3

3

要获取成员变量或函数的地址,请使用:

&MyClass::MyMember

要调用成员函数指针,请使用以下之一:

(my_class.*ptr_to_member)( /* arguments */ )
(my_ptr->*ptr_to_member)( /* arguments */ )

我在 Google 上找到的包含更多信息的随机链接:http ://www.goingware.com/tips/member-pointers.html

于 2010-03-04T13:08:52.470 回答
3

为了调用对象的成员函数,您需要提供两件事:

  1. 成员函数的地址,如前所述,您可以通过编写&my_class::my_member
  2. 指向要为其调用成员函数的对象实例的指针(或引用)

精神语义动作期望您提供暴露某个接口的函数或函数对象。在您的情况下,预期的界面是:

void func(Iterator first, Iterator Last);

其中 Iterator 是用于调用 parse 函数的迭代器类型(可通过 访问typename ScannerT::iterator_t)。您需要做的是创建一个函数对象,在调用您的成员函数的同时公开上述接口。虽然这可以手动完成,但这样做充其量是乏味的。创建函数对象的最简单方法是使用 Boost.Bind:

prog = (alpha_p >> *alnum_p)
       [
           boost::bind(&ParserActions::do_prog, self.action)
       ];

这将为您创建所需的函数对象,绑定和包装您的成员函数。

所有这些都假设您的成员函数不接受任何参数。如果您需要传递这对迭代器,语义操作将被调用到您的函数中,该构造需要编写为:

prog = (alpha_p >> *alnum_p)
       [
           boost::bind(&ParserActions::do_prog, self.action, _1, _2)
       ];

指示函数对象将其第一个和第二个参数转发给绑定函数。

于 2010-03-04T14:23:33.727 回答
1

函数指针和成员函数指针有一个根本的区别:

  • 必须使用正确类型的参数调用函数指针,

  • 必须使用正确类型的对象和正确类型的参数调用成员函数指针。

像从对象中那样构建成员函数指针不会在指针中注册对象。

如果你想要这样的东西,有各种各样的库这样做(你有一个 boost 标签,请参阅绑定和信号以获取此类示例)。

于 2010-03-04T13:31:54.210 回答