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

C++23中如何基于std::views::join的结果构建std::map?

嵌套范围经views::join扁平化后转std::map编译失败的解决方法

我使用GCC 14的C++23模式编写了以下代码,将嵌套视图扁平化后转换为std::vector可正常运行:

auto c = std::ranges::views::iota(1, 5)
        | std::ranges::views::transform([](int const v){
                return std::ranges::views::iota(1, 3)
                    | std::ranges::views::transform([v](int const w){
                            return std::make_pair(v, std::format("[{}/{}]", v, w));
                    });
        })
        | std::ranges::views::join
        | std::ranges::to<std::vector>();

但将目标容器改为std::map后,代码无法编译,编译器报错涉及std::construct_at构建map节点失败,且仅在嵌套范围经views::join扁平化后转map时出现该问题:

auto c = std::ranges::views::iota(1, 5)
        | std::ranges::views::transform([](int const v){
                return std::ranges::views::iota(1, 3)
                    | std::ranges::views::transform([v](int const w){
                            return std::make_pair(v, std::format("[{}/{}]", v, w));
                    });
        })
        | std::ranges::views::join
        | std::ranges::to<std::map>();

问题原因

std::map要求键必须唯一,但你的代码中,同一个v值(比如1)会生成两个键相同的std::pair:(1, "[1/1]")和(1, "[1/2]")。重复的键违反了std::map的约束,导致容器构造失败,编译器的错误信息只是底层实现的表现,本质是键重复问题。

解决方法

方案1:保证键的唯一性

修改生成的pair,让键成为唯一值,比如将键改为std::pair<int, int>(结合v和w),这样每个键都是独一无二的:

auto c = std::ranges::views::iota(1, 5)
        | std::ranges::views::transform([](int const v){
                return std::ranges::views::iota(1, 3)
                    | std::ranges::views::transform([v](int const w){
                            // 将键改为(v, w),确保唯一性
                            return std::make_pair(std::make_pair(v, w), std::format("[{}/{}]", v, w));
                    });
        })
        | std::ranges::views::join
        | std::ranges::to<std::map>();

方案2:改用支持重复键的容器

如果业务逻辑允许同一个键对应多个值,直接使用std::multimap(或std::unordered_multimap),它允许重复键,无需修改生成pair的逻辑:

auto c = std::ranges::views::iota(1, 5)
        | std::ranges::views::transform([](int const v){
                return std::ranges::views::iota(1, 3)
                    | std::ranges::views::transform([v](int const w){
                            return std::make_pair(v, std::format("[{}/{}]", v, w));
                    });
        })
        | std::ranges::views::join
        | std::ranges::to<std::multimap>();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 00:40:17