c++ - 为什么 std::ranges::view_interface 使用 CRTP

标签 c++ c++20 range-v3 std-ranges

根据cppreference,定义 View 的辅助类模板view_interface使用奇怪的循环模板模式 (CRTP) 技术。

它们背后的设计理念是什么?与在派生类中覆盖虚拟基类方法相比,是否有显着优势?

最佳答案

如果你给一个基类虚函数,那么它就有那些函数。总是。它永远具有这些功能,并且从它派生的每个类都将继承这些功能。

view_interface 有一个 empty 函数当且仅当类型的范围类别是 forward_range 时。也就是说,如果 begin 返回前向迭代器,并且 end 返回该迭代器的标记,则 empty 存在。但是您只能测试是否可以查询派生类的属性。基类不能这样做......除非你通过给它派生类类型来允许它。这意味着它必须是一个模板参数,基类是一个模板。

因此,您正在使用 CRTP。

根据派生范围类的迭代器类别提供或不提供公共(public)功能是该类的整点。唯一的选择是为每种迭代器类型设置一组基类。因此,您需要 forward_view_interface 用于前向范围,contiguous_view_interface 用于连续范围,等等。这会很痛苦。但它会开始经历乘法爆炸,因为 view_interface 提供的一些属性与迭代器类别正交。

例如,如果范围是大小范围,则提供 size。但这可能发生在任何迭代器类别中,甚至是输入迭代器。所以你现在需要 sized_forward_view_interface

或者您可以只使用 CRTP。

关于c++ - 为什么 std::ranges::view_interface 使用 CRTP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66094846/

相关文章:

c++ - 如何在抽象类中创建允许返回任何类型的 C++ 虚函数

C++-Build : After editing a file in a project the build process takes a long time. 如何找出负责的文件/类?

c++ - Qt QTimer 这样停止安全吗?

c++ - 如何通过标准元组操作正确转发和使用 constexpr 结构的嵌套元组

c++ - 传递给返回 awaitable 的函数的临时对象在使用 co_await 暂停点后是否仍然有效

c++ - forward_iterator 概念的冗余?

c++ - Range-v3 View 组合和 View 计算并行化

c++ - 流 >> 读取最后一行两次

c++ - 为什么 `iota(0) | take(0)` 不是 C++20 中的模型 range::sized_range?

c++ - Range-v3 view::sliding(n) 返回元组(如果 n 在编译时已知)