std::ranges::range

来自cppreference.com
 
 
范围库
范围适配器
 
<tbody> </tbody>
在标头 <ranges> 定义
template< class T > concept range = requires( T& t ) { ranges::begin(t); // 对向前迭代器保持相等性 ranges::end (t); };
(C++20 起)

range 概念定义允许通过指代元素范围的迭代器和哨位,在它的元素上迭代的类型。

语义要求

给定表达式 E 使得 decltype((E))T,只有在满足以下全部条件时 T 才会实现 range

  • [ranges::begin(E)ranges::end(E)) 代表范围
  • ranges::begin(E)ranges::end(E) 均有均摊常量时间复杂度且不会以对于保持相等性的表达式可观察的方式更改 E 的值。
  • 如果 ranges::begin(E) 的类型实现 forward_iterator,那么 ranges::begin(E) 保持相等性(换言之,向前迭代器支持多趟算法)。

注解

一个典型的 range 类只需要提供两个函数:

  1. 成员函数 begin(),它的返回类型实现 input_or_output_iterator
  2. 成员函数 end(),它的返回类型实现 sentinel_for<It>,其中 Itbegin() 的返回类型。

它们也可以作为非成员函数实现,通过实参依赖查找找到。

示例

#include <ranges>

// 最小化的范围
struct SimpleRange
{
    int* begin();
    int* end();
};
static_assert(std::ranges::range<SimpleRange>);

// 不是范围:没有 begin/end
struct NotRange
{
    int t {};
};
static_assert(!std::ranges::range<NotRange>);

// 不是范围:begin 返回的不是 input_or_output_iterator
struct NotRange2
{
    void* begin();
    int* end();
};
static_assert(!std::ranges::range<NotRange2>);

int main() {}

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
LWG 3915 C++20 ranges::begin(t)ranges::end(t) 不要求有隐式的表达式变种 移除此多余描述