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

