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

C++20中Views管道与ranges adjacent_find迭代器无效错误修复

问题原因分析
  • std::ranges::adjacent_find(带自定义二元谓词的重载)要求输入范围满足**forward_range**概念——即迭代器至少是forward iterator,支持多次遍历、保存迭代器后复用。
  • 你的代码中,第一个std::views::transform(get_vectors)按值返回std::vector<int>,导致transform_view生成的元素是临时vector对象(右值)。join_view处理这种产出右值范围的视图时,生成的迭代器属于input iterator类别(临时对象会被销毁,无法安全保存迭代器并重新访问元素)。后续的transform视图不会提升迭代器类别,最终all_ints是input range,不满足adjacent_find的要求,触发编译错误。
修复方案

方案1:移除冗余的transform视图

你的第一个transform(get_vectors)完全多余——vectors_of_ints本身就是std::vector<std::vector<int>>,直接通过std::views::join就能展开所有子vector的元素:

#include <algorithm>
#include <ranges>
#include <vector>

auto main() -> int
{
    std::vector<std::vector<int>> vectors_of_ints {
        {1, 2, 3},
        {4, 5, 6}
    };

    // 直接展开嵌套vector,得到所有int的视图
    auto all_ints = vectors_of_ints | std::views::join;

    // 检查是否存在不相等的相邻元素(即不是所有值都相同)
    auto status = std::ranges::adjacent_find(all_ints, std::not_equal_to{}) != std::ranges::end(all_ints);

    return status;
}

方案2:保留transform时返回引用(针对实际代码有复杂逻辑的场景)

如果实际代码中get_vectors有额外处理逻辑,必须保留transform,那么修改lambda返回子vector的引用,确保transform_view产出左值范围:

auto get_vectors = [](const std::vector<int>& v) -> const std::vector<int>& { 
    // 这里可以添加自定义逻辑
    return v; 
};
// 后续join后的迭代器会提升为forward iterator,满足adjacent_find要求
auto all_ints = vectors_of_ints
       | std::views::transform(get_vectors)
       | std::views::join;

额外说明:逻辑澄清

  • 你当前的代码逻辑是检查是否存在不相等的相邻元素(即不是所有值都相同),返回true表示存在差异。
  • 如果要检查所有值是否唯一(无重复),仅用adjacent_find不够,需要先排序再检查:
auto sorted_ints = all_ints | std::views::sort;
auto has_duplicates = std::ranges::adjacent_find(sorted_ints) != std::ranges::end(sorted_ints);
auto all_unique = !has_duplicates;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:40:58