我正在使用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) {
}
};
答案 0 :(得分:3)
要获取成员变量或函数的地址,请使用:
&MyClass::MyMember
要调用成员函数指针,请使用以下之一:
(my_class.*ptr_to_member)( /* arguments */ )
(my_ptr->*ptr_to_member)( /* arguments */ )
我在Google上找到的随机链接有更多信息:http://www.goingware.com/tips/member-pointers.html
答案 1 :(得分:3)
为了调用对象的成员函数,您需要提供两件事:
&my_class::my_member
Spirit语义操作希望您提供暴露某个接口的函数或函数对象。在您的情况下,预期的界面是:
void func(Iterator first, Iterator Last);
其中Iterator是用于调用解析函数的迭代器类型(可通过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)
];
指示函数对象将其第一个和第二个参数转发给绑定函数。
答案 2 :(得分:1)
函数指针和成员函数指针之间存在根本区别:
必须使用正确类型的参数调用函数指针
必须使用正确类型的对象和正确类型的参数调用成员函数指针。
像对象一样构建成员函数指针不会在指针中注册对象。
如果你想要这样的东西,有各种各样的库这样做(你有一个boost标签,参见bind和信号这样的例子)。