【问题标题】:Why std::ranges::view_interface using CRTP为什么 std::ranges::view_interface 使用 CRTP
【发布时间】:2021-05-11 15:48:42
【问题描述】:

根据 cppreference,用于定义视图 view_interface 的帮助程序类模板使用奇怪的重复模板模式 (CRTP) 技术。

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

【问题讨论】:

  • 一个视图是非拥有的,并且是轻量级的。记住这一点。继承不是。
  • @doug:从具有虚函数的类型继承并不是轻量级的。
  • @doug single_view<std::function<void()>> 拥有而不是相当轻量级。
  • @NicolBolas 我应该更清楚一点,说不,而不是不。

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


【解决方案1】:

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

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

因此,您正在使用 CRTP。

根据派生范围类的迭代器类别提供或不提供通用函数是该类的整点。唯一的选择是为每个迭代器类型设置一堆基类。所以你有forward_view_interface 用于前向范围,contiguous_view_interface 用于连续范围等。那会很痛苦。但它会开始经历乘法爆炸,因为view_interface 提供的一些属性与迭代器类别正交。

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

或者你可以只使用 CRTP。

【讨论】:

    猜你喜欢
    • 2020-01-11
    • 2021-11-17
    • 2022-12-15
    • 2020-09-22
    • 2021-10-01
    • 1970-01-01
    • 2021-02-18
    • 2022-01-18
    • 1970-01-01
    相关资源
    最近更新 更多