我正在编写一个Boost Spirit语法来将文本解析为这些结构的向量:
struct Pair
{
double a;
double b;
};
BOOST_FUSION_ADAPT_STRUCT(
Pair,
(double, a)
(double, a)
)
这个语法有这样的规则:
qi::rule<Iterator, Pair()> pairSequence;
然而,pairSequence
的实际语法是:
double_ % separator
我希望这个语法产生Pair
,a
等于double,b
等于某个常量。我想做这样的事情:
pairSequence = double_[_val = Pair(_1, DEFAULT_B)] % separator;
当然,上面没有编译。我尝试将构造函数添加到Pair
,但我仍然遇到编译错误(没有匹配函数来调用'Pair :: Pair(const boost :: phoenix :: actor&gt;&amp;,double)' )。
答案 0 :(得分:6)
首先,pairSequence
的签名必须是:
qi::rule<Iterator, std::vector<Pair>()> pairSequence;
作为列表运算符公开std::vector<Pair>
作为其属性。
从语义动作中调用的所有函数都必须是“懒惰的”,所以你需要利用凤凰:
namespace phx = boost::phoenix;
pairSequence =
double_[
phx::push_back(_val,
phx::construct<Pair>(_1, phx::val(DEFAULT_B))
)
] % separator
;
另一种可能性是向Pair
添加(非显式)构造函数:
struct Pair
{
Pair(double a) : a(a), b(DEFAULT_B) {}
double a;
double b;
};
允许简化语法:
pairSequence = double_ % separator;
完全依赖于Spirit的内置属性传播规则。
顺便说一下,要使其中任何一个工作,您不需要将Pair
作为Fusion序列进行调整。