C++20:从函数返回std::ranges::view的问题与实践
C++20视图优化遗留代码:解决多类型视图返回编译问题
问题背景
原遗留代码的热点路径中存在如下函数:
std::vector<engagementIndex> getEngagementsForDay(DayIndex day) { std::vector<engagementIndex> outputVector; for(EngagementIndex engagement : engagements){ if(getDay(engagement) == day) { outputVector.push_back(engagement); } } return outputVector; }
该函数返回的向量通常仅包含不足10个short类型索引,但被调用数十万次,频繁的内存分配成为性能瓶颈,计划改用C++20视图避免内存分配。
核心问题
- 视图返回类型与编译失败问题:
团队不推荐使用auto作为返回类型,且即便尝试用auto,由于需要根据运行时条件返回4种不同类型的视图,直接导致编译失败:- 空视图:
return std::ranges::empty_view<EngagementIndex>(); - 完整向量视图:
return engagements | std::views::all; - 向量部分视图:
return engagements | std::views::take(size); - 条件过滤后的向量视图:
return engagements | std::views::filter(engagementDayFilter(day));
上述每种返回语句生成的视图类型均不相同,无法满足函数单一返回类型的要求。
- 空视图:
解决方案
将所有场景逻辑整合到自定义单一过滤器中,放弃多段管道过滤的方式,确保返回类型统一,同时提升代码可读性:
return engagements | std::views::filter(myFilter1(day));
其中myFilter1需整合原有的空、完整、截取、条件过滤逻辑,根据day和相关参数判断每个engagement是否符合返回条件。
实践结果
从返回vector拷贝改为返回视图后,目标函数不再处于热点路径,性能提升幅度在1%-5%之间。
内容的提问来源于stack exchange,提问作者Dr Phil
相关产品推荐
相关产品推荐

