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

如何使用Ranges/Range-v3将两列CSV读取为std::map<int,int>

实现方案

你现有代码的两个问题可以通过调整视图流水线逻辑一次性解决,核心改动点有两个:

  • 放弃join+chunk(2)的拍平再分组逻辑:这种写法会丢失行边界信息,一旦某行逗号数量不对就会出现跨行配对的错误,且chunk的分组大小是运行时参数,无法做长度校验
  • 逐行完成拆分、类型转换后直接构造std::pair<int,int>,最终直接转换为std::map即可

完整可运行代码

#include <boost/hof/lift.hpp>
#include <iostream>
#include <map>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/istream.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/split.hpp>
#include <string>
#include <utility>

using ranges::to;
using namespace ranges::views;

constexpr auto splitAtComma = [](auto const& r) { return r | split(','); };
constexpr auto rngToString = [](auto const& r) { return r | to<std::string>(); };
constexpr auto strToInt = BOOST_HOF_LIFT(std::stoi);

// 逐行处理:拆分逗号 -> 转字符串 -> 转int -> 转为pair(自动校验每行正好2个元素)
constexpr auto lineToPair = transform(splitAtComma)
                          | transform(rngToString)
                          | transform(strToInt)
                          | to<std::pair<int, int>>();

int main() {
    auto lines = istream<std::string>(std::cin);
    // 所有pair直接转换为std::map<int,int>
    auto coordMap = lines | lineToPair | to<std::map<int, int>>();

    // 验证输出
    for (auto [k, v] : coordMap) {
        std::cout << k << ":" << v << '\n';
    }
}

关键说明

  • to<std::pair<int,int>>()会校验输入范围的元素个数恰好为2,长度不符合时会直接抛出ranges::bad_conversion异常,不会出现静默的跨行错配问题,相比chunk(2)的方案安全性高很多
  • 流水线最终输出的是std::pair<int,int>的视图,ranges::to<std::map<int,int>>()可以直接将这类键值对范围转换为目标map类型,不需要额外处理嵌套结构
  • 运行你给出的测试输入,程序会正确输出:
1:2
11:7
12:40

注:std::map是有序关联容器,输出会自动按key升序排列


补充说明

如果你使用C23标准库自带的Ranges实现,标准库的std::ranges::to对pair和map的转换支持和range-v3逻辑一致;C20及更早版本没有该工具,直接使用range-v3的实现兼容性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 16:31:06