You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Boost Spirit qi可选分支操作符无法填充结构体全部属性值问题

问题原因

该问题由Boost Spirit Qi的交替解析符|的属性合成规则导致:
|要求两个分支的属性签名完全一致,才能将分支内的属性元素自动展开合并到父规则的属性序列中。如果Qi无法推断出两个分支返回完全相同的属性结构,会将整个交替分支的属性包装为单个boost::variant对象,而不是展开为4个独立的double值。

你的代码中,B分支和C分支逻辑上都返回4个double,但由于缺少显式属性声明,Qi没有将两个分支的属性识别为长度为4的double序列,而是将整个(B分支|C分支)的属性作为单个值绑定到了MyStruct的r5字段,剩余的r6/r7/r8未被赋值,保留了未初始化的垃圾值,这就是你看到异常数值的原因。

没有加C分支时,后续是连续的4个double解析规则,属性会直接依次绑定到r5到r8,因此结果符合预期。

解决方法

你可以通过显式指定交替分支的属性类型,引导Qi正确合成属性,有两种常用实现方案:

方案1:使用qi::as强制指定属性结构

直接在交替分支外层加qi::as声明,强制Qi将分支内容解析为长度为4的double序列:

// 先修正real_parser的显式实例化,避免类型推断问题
qi::real_parser<double> d19_12;

qi::rule<string::const_iterator, MyStruct()> gr =
  qi::lit("A") >> d19_12 >> d19_12 >> d19_12 >> d19_12 >> CRLF
  // 强制指定交替分支返回4个double的fusion序列
  >> qi::as<boost::fusion::vector<double, double, double, double>>()[
       (qi::lit('B') >> d19_12  >> d19_12 >> d19_12 >> d19_12 >> CRLF)
       |
       (qi::lit('C') >> d19_12  >> d19_12 >> d19_12 >> +qi::lit('_') >> qi::attr(0.0) >> CRLF)
     ];

方案2:单独定义子规则显式声明属性

将第二行的解析逻辑拆分为独立子规则,显式指定其属性类型,避免推断错误:

qi::real_parser<double> d19_12;
// 定义第二行解析规则,显式声明返回4个double
qi::rule<string::const_iterator, boost::fusion::vector<double, double, double, double>()> second_line_rule =
  (qi::lit('B') >> d19_12  >> d19_12 >> d19_12 >> d19_12 >> CRLF)
  |
  (qi::lit('C') >> d19_12  >> d19_12 >> d19_12 >> +qi::lit('_') >> qi::attr(0.0) >> CRLF);

qi::rule<string::const_iterator, MyStruct()> gr =
  qi::lit("A") >> d19_12 >> d19_12 >> d19_12 >> d19_12 >> CRLF
  >> second_line_rule;

两种方案都可以让Qi正确将交替分支的4个double值依次绑定到r5到r8,得到你期望的解析结果。


内容的提问来源于stack exchange,提问作者Anton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:39:03