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

C++20中如何将std::ranges::views作为参数传递?

问题解决:兼容std::vector和视图的打印函数

问题背景

你现有一个只读整数列表的打印函数:

void printElements(const std::vector<int> &integersList)
{
    std::for_each(integersList.begin(), integersList.end(), [](const auto& e){
        std::cout << e << "\n";
    });
}

同时通过std::views::filter生成了偶数视图:

std::vector<int> vec{1,2,3,4,5,6,7,8,9,10};
auto evenList = vec | std::views::filter([](auto i){ return i % 2 == 0; });

调用printElements(evenList)时编译失败,需要解决该问题,且希望用单个函数同时处理std::vector和视图类型。

编译失败原因

核心问题是类型不匹配:std::views::filter生成的是std::ranges::filter_view类型对象,它与std::vector<int>属于完全不同的类型体系,无法隐式转换为const std::vector<int>&,导致函数调用无法匹配。

解决方案:单模板函数兼容所有范围类型

不需要编写两个函数,只需将printElements改为模板函数,让它接受任何满足C++20**输入范围(input_range)**概念的类型即可。std::vector和所有标准视图都符合这个概念,因此能被统一处理。

修改后的代码

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

template<std::ranges::input_range R>
void printElements(const R& range)
{
    std::ranges::for_each(range, [](const auto& e){
        std::cout << e << "\n";
    });
}

兼容旧版std::for_each的写法

如果你更习惯使用传统的std::for_each,也可以用std::ranges::begin和std::ranges::end来适配范围类型:

template<std::ranges::input_range R>
void printElements(const R& range)
{
    std::for_each(std::ranges::begin(range), std::ranges::end(range), [](const auto& e){
        std::cout << e << "\n";
    });
}

测试验证

int main()
{
    std::vector<int> vec{1,2,3,4,5,6,7,8,9,10};
    printElements(vec); // 正常处理std::vector
    
    auto evenList = vec | std::views::filter([](auto i){ return i % 2 == 0; });
    printElements(evenList); // 正常处理filter视图
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 12:15:39