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

使用Boost Spirit解析字符后跟可变数量整数的编译问题

问题:Boost Spirit解析可变数量整数编译错误

需求

解析以下格式的字符串:

f 1 2 3 4
f 1 2 3
f 1 2 3 4 5

出错的代码

using boost::spirit::qi::uint_;
using boost::spirit::qi::double_;
using boost::spirit::qi::_1;
using boost::spirit::qi::phrase_parse;
using boost::spirit::ascii::space;
using boost::phoenix::ref;
using boost::phoenix::push_back;

std::vector<unsigned int> v;

r = phrase_parse(first_, last_,

    //  Begin grammar
    (
        'f' >> uint_[push_back(ref(v), _1)] >>*(uint_[push_back(ref(v), _1)])
    )
    ,
    //  End grammar

    space);//  Begin grammar

编译错误

  • Error C2064: term does not evaluate to a function taking 2 arguments
  • Error C2668: 'boost::phoenix::ref': ambiguous call to overloaded function
  • Error C2780: 'bool boost::spirit::qi::phrase_parse(Iterator &,Iterator,Expr &,const Skipper &,boost::spirit::qi::skip_flag)': expects 5 arguments - 3 provided

环境说明

使用Boost 1.55版本和MSVC 2015(无法更换)

可正常运行的代码(固定数量整数)

unsigned int v1 = 0, v2 = 0, v3 = 0;

r = phrase_parse(first_, last_,

     //  Begin grammar
     (
          'f' >> uint_[ref(v1) = _1]
      >> uint_[ref(v2) = _1] >> uint_[ref(v3) = _1]
     ),
    //  End grammar

   space);

问题分析与修复

1. 核心问题拆解

旧代码的错误集中在三个点:phrase_parse参数传递、Phoenix动作绑定歧义、语法规则冗余。

2. 修复后的代码

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <vector>
#include <string>

int main() {
    namespace qi = boost::spirit::qi;
    namespace phoenix = boost::phoenix;
    using qi::uint_;
    using qi::phrase_parse;
    using qi::_1;
    using qi::ascii::space;
    using phoenix::ref;
    using phoenix::push_back;

    std::string input = "f 1 2 3 4";
    auto first = input.begin();
    auto last = input.end();
    std::vector<unsigned int> v;
    bool r;

    // 用+uint_替代冗余的uint_>>*uint_,匹配1个或多个整数
    r = phrase_parse(first, last,
        'f' >> +uint_[push_back(ref(v), _1)],
        space);

    return 0;
}

3. 关键修复点

  • 简化语法规则:使用+uint_替代uint_ >> *uint_,+表示匹配1个或多个目标规则,既符合需求(f后至少有一个整数),又避免重复编写相同的Phoenix动作,减少绑定错误。
  • 解决ref歧义:通过命名空间限定phoenix::ref,避免MSVC 2015中与std::ref的命名冲突,消除C2668错误。
  • 修正phrase_parse参数:确保迭代器参数正确传递,且r明确声明为bool类型,解决C2780的参数数量不匹配问题。
  • 清理冗余语法:移除不必要的括号和错位注释,避免编译器解析歧义。

4. 错误原因详解

  • C2780错误:旧代码中可能存在迭代器未按引用传递、或语法错误导致编译器匹配到错误的phrase_parse重载,修复后使用标准的4参数重载即可解决。
  • C2064与C2668错误:旧代码中重复的push_back动作在Boost 1.55与MSVC 2015的组合下,触发了Phoenix函数对象的绑定歧义,简化规则后只保留一次动作,即可消除这类错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:32:55