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

使用Boost Spirit将双整数序列解析到STL vector遇问题求助

嘿,我之前刚好折腾过Boost Spirit的属性绑定,太懂你这种困惑了!咱们一步步拆解问题:

首先你可能误解了文档里的描述——int_ >> int_的属性并不是直接的std::vector<int>,而是boost::fusion::vector<int, int>(一个fusion元组)。文档里说“vector表示任何存储A类型元素的STL容器”,那是针对重复序列解析器的情况(比如*int_、+int_或者repeat(2)[int_]这类会多次匹配同一规则的解析器),而a >> b这种顺序拼接两个独立规则的写法,属性是fusion的tuple类型,对应每个子规则的属性依次排列。

这就是为什么你给int_>>int_绑定接受std::vector<int>的动作会失败——Spirit找不到从fusion tuple到vector的自动转换(或者说你没触发这个转换)。

给你几个解决思路,附代码示例:

1. 改用重复解析器直接生成vector属性

如果你的需求就是解析固定数量的整数到vector里,用repeat(2)[int_]是最直接的,它的属性天然就是std::vector<int>:

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

namespace qi = boost::spirit::qi;

int main() {
    std::string input = "123 456";
    std::vector<int> nums;

    // 直接解析到vector,动作也能直接接vector参数
    bool ok = qi::parse(input.begin(), input.end(), 
        repeat(2)[int_][[](const std::vector<int>& vec) {
            for (int num : vec) std::cout << num << " ";
        }], nums);
}

2. 适配fusion tuple到vector,保留int_>>int_写法

如果你一定要用int_>>int_的结构,可以用qi::as<std::vector<int>>()来强制让Spirit把fusion tuple转换为vector:

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

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;

void process_vec(const std::vector<int>& vec) {
    // 这里写你的vector处理逻辑
}

int main() {
    std::string input = "123 456";
    std::vector<int> nums;

    bool ok = qi::parse(input.begin(), input.end(), 
        qi::as<std::vector<int>>()[int_ >> int_][phx::bind(&process_vec, qi::_1)], nums);
}

3. 直接处理fusion tuple的动作

如果不想转vector,也可以把动作的参数改成fusion tuple的类型,或者直接绑定两个单独的属性:

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

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;

void process_two_ints(int a, int b) {
    std::vector<int> vec;
    vec.push_back(a);
    vec.push_back(b);
    // 后续处理vector的逻辑
}

int main() {
    std::string input = "123 456";

    // 直接绑定两个子规则的属性
    qi::parse(input.begin(), input.end(), 
        int_ >> int_[phx::bind(&process_two_ints, qi::_1, qi::_2)]);
}

核心记住这一点:Spirit里不同的解析器组合生成的属性类型是不一样的,顺序拼接(>>)生成fusion元组,重复匹配生成STL容器,搞清楚这个对应关系就不会踩坑啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:30:25