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

使用Range-v3从结构体提取向量并扁平化编译失败求助

问题描述

使用C++17及Ubuntu22.10上的librange-v3-dev(0.11.0-2),需要从包含vector成员的结构体中提取所有vector并扁平化,且不在堆上创建新vector。编写代码后期望输出「1 2 3 4 5 6 7」,但执行编译命令c++ --std=c++17 range.cpp时出现编译错误:

range.cpp: In function 'int main()':
range.cpp:16:56: error: no match for 'operator|' (operand types are 'ranges::transform_view<ranges::ref_view<std::vector >, main()::<lambda(const auto:10&)> >' and 'const ranges::views::view_closureranges::views::join_fn')
16 | auto flattened_range = As | view::transform(getter)| view::join;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ~~~~~~~~~~
| | |
| | const ranges::views::view_closureranges::views::join_fn
| ranges::transform_view<ranges::ref_view<std::vector >, main()::<lambda(const auto:10&)> >
In file included from /usr/include/c++/11/regex:39,

对应的代码:

#include <range/v3/all.hpp>
#include <vector>
#include <iostream>

struct A {
    std::vector<int> vv;
};

int main()
{
    using namespace ranges;
    std::vector<A> As = { A{{1,2,3,4}}, A{{5,6,7}} };
    
    auto getter = [](const auto&r) { return r.vv; };

    auto flattened_range = As | view::transform(getter)| view::join;

    for (auto i : flattened_range){
      std::cout << i << " "; 
    }

    return 0;
}

错误原因

在range-v3 0.11.0版本中,view::join要求上游transform_view返回的是视图类型或range的引用,而你的lambda通过return r.vv;返回了std::vector<int>的拷贝,这种值类型无法被join正确识别,导致运算符匹配失败。

修改方法

有两种可行的修改方式,都不会在堆上创建新vector:

  1. 返回vector的视图
    用ranges::views::all将vector包装为视图,这样transform后输出的是视图序列,符合join的要求:

    #include <range/v3/all.hpp>
    #include <vector>
    #include <iostream>
    
    struct A {
        std::vector<int> vv;
    };
    
    int main()
    {
        using namespace ranges;
        std::vector<A> As = { A{{1,2,3,4}}, A{{5,6,7}} };
        
        // 返回vector的视图而非拷贝
        auto getter = [](const auto& r) { return views::all(r.vv); };
    
        auto flattened_range = As | views::transform(getter) | views::join;
    
        for (auto i : flattened_range){
          std::cout << i << " "; 
        }
    
        return 0;
    }
    
  2. 返回vector的const引用
    显式让lambda返回const std::vector<int>&,确保transform后传递的是原vector的引用而非拷贝:

    auto getter = [](const auto& r) -> const std::vector<int>& { return r.vv; };
    

两种修改方式都能编译通过并输出期望的结果,且不会额外创建堆上的vector,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:56:02