问题描述
我在 cppreference 上找到了这个:
以下类型派生自 std::ranges::view_interface 并执行 不声明自己的大小成员函数,但他们不能使用 默认实现,因为它们的迭代器和哨兵类型 从不满足 sized_sentinel_for:
std::ranges::basic_istream_view
std::ranges::filter_view
std::ranges::join_view
std::ranges::split_view
std::ranges::take_while_view
这是有道理的,因为这些视图无法在 O(1) 中计算大小。但我不明白为什么不为视图创建多个基类,例如类似 view_interface 但没有大小成员的东西?
我认为一个可能的原因是范围已经是一个非常复杂的库,但也许我错过了其他东西。
如果您想知道为什么这是一个问题:也许不是,但我认为/觉得这会让用户感到困惑,因为这些视图具有永远无法工作的成员函数。
注意:我知道我可以使用距离,这是一个关于设计的问题。
解决方法
类模板不是类。 std::ranges::view_interface
不是任何东西的基类。
std::ranges::view_interface<std::ranges::filter_view<V,Pred>>
没有有 size
成员。 std::ranges::view_interface
的其他实例也是如此,但模板的一个实例总是有可能拥有另一个没有的成员。
std::ranges::view_interface
的文档确实提到 size
仅在(除其他外)其标记和迭代器类型满足 std::sized_sentinel_for
时才存在。
我更喜欢使用一个名称来计算适当的能力,而不是为微妙不同的能力使用大量不同的名称。它更具可扩展性,如果在以后的标准中定义了其他成员,则一切都会自动获得它支持的成员,而无需更改例如sized_forward_view_interface
到 foobar_sized_forward_view_interface
。