如何定义类型擦除的std::ranges::view适配分离编译场景?
C++范围视图返回类型擦除解决方案
当需要将范围视图的生产者(getValidObjectsView)和消费者(consumeValidObjects)分离到不同翻译单元时,由于std::ranges::views::filter的返回类型依赖匿名lambda,无法直接在头文件中声明具体类型。可以通过以下方式解决:
方法:使用标准库std::ranges::any_view(推荐)
std::ranges::any_view是C++20引入的类型擦除工具,专门用于存储满足特定范围概念的任意对象,完美适配你的场景。
头文件声明
#include <ranges> struct Object { bool isValid() const; // 其他成员定义 }; // 定义类型擦除后的范围类型,指定引用类型避免对象拷贝 using ObjectsIterable = std::ranges::any_view<const Object&>; ObjectsIterable getValidObjectsView(); void consumeValidObjects(ObjectsIterable validObjectsView);
实现文件(.cpp)
#include "your_header.h" #include <vector> #include <ranges> // 假设获取对象集合的函数 std::vector<Object> getObjects(); ObjectsIterable getValidObjectsView() { std::vector<Object> objects = getObjects(); return objects | std::ranges::views::filter( [](const Object& obj) { return obj.isValid(); } ); } void consumeValidObjects(ObjectsIterable validObjectsView) { for (const auto& obj : validObjectsView) { // 处理有效对象的业务逻辑 } }
any_view会擦除底层范围的具体类型,仅保留可遍历const Object&的核心特性,带来的运行时开销极小,适合绝大多数场景。如果需要支持修改对象,可将类型改为std::ranges::any_view<Object&>。
内容的提问来源于stack exchange,提问作者Dmitry Kuzminov
相关产品推荐
相关产品推荐

