说我是否有一个简单的结构:
struct huh { char xxx; };
在没有使用Boost Fusion改编的结构的情况下,我想在Spirit规则的语义动作中找到一个更简单的代理来操作成员变量。当然,这当然不起作用:
_val.xxx = _1
但是我希望得到一些清洁而不是与凤凰绑定:
bind(&huh::xxx, _val) = _1
以下是编辑clang和g ++的简单图片的工作示例:
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/phoenix/bind/bind_member_variable.hpp>
struct huh { char xxx; };
int main() {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
qi::rule<std::string::const_iterator, huh(), ascii::space_type> start;
start = qi::char_[
phx::bind(&huh::xxx, qi::_val) = qi::_1
];
return 0;
}
有什么想法吗?
答案 0 :(得分:2)
与融合绑定正是使它“与凤凰绑定”的“一点点更清洁”的粘合剂。
所以,有你的解决方案。或者,考虑您的表达模板,可能:
auto _xxx = phx::bind(&huh::xxx, _val);
所以你可以写:
start = char_[ _xxx = _1 ];
或者,使用函数或自定义点:
添加特征
namespace boost { namespace spirit { namespace traits {
template <> struct assign_to_attribute_from_value<huh, char, void> {
static void call(char c, huh& attr) { attr.xxx = c; }
};
} } }
您现在可以简单地写
qi::rule<std::string::const_iterator, huh(), ascii::space_type> start;
start = qi::char_;
<强> Live On Coliru 强>
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
struct huh { char xxx; };
namespace boost { namespace spirit { namespace traits {
template <> struct assign_to_attribute_from_value<huh, char, void> {
static void call(char c, huh& attr) { attr.xxx = c; }
};
} } }
int main() {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
qi::rule<std::string::const_iterator, huh(), ascii::space_type> start;
start = qi::char_;
}