为什么 std::ranges::view_interface 使用 CRTP

问题描述

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

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

解决方法

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

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

因此,您使用的是 CRTP。

是否提供基于派生范围类的迭代器类别的通用函数是类的全部内容。唯一的选择是为每个迭代器类型拥有一堆基类。所以你有 forward_view_interface 用于前向范围,contiguous_view_interface 用于连续范围等。这会很痛苦。但它会开始经历乘法爆炸,因为 view_interface 提供的某些属性与迭代器类别正交。

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

或者您可以只使用 CRTP。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...