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
相关产品推荐
相关产品推荐

