std::ranges::views::adjacent, std::ranges::adjacent_view, std::ranges::views::pairwise

来自cppreference.com
< cpp‎ | ranges
 
 
范围库
范围适配器
adjacent_viewviews::adjacent
(C++23)(C++23)
views::pairwise
(C++23)
 
 
在标头 <ranges> 定义
template< ranges::forward_range V, std::size_t N >

    requires ranges::view<V> && (N > 0)
class adjacent_view

    : public ranges::view_interface<adjacent_view<V, N>>
(1) (C++23 起)
namespace views {

    template< std::size_t N >
    constexpr /* 未指明 */ adjacent = /* 未指明 */ ;

}
(2) (C++23 起)
namespace views {

    inline constexpr auto pairwise = adjacent<2>;

}
(3) (C++23 起)
调用签名
template< ranges::viewable_range R >

    requires /* 见下文 */

constexpr ranges::view auto adjacent<N>( R&& r );
(C++23 起)
1) adjacent_view 是接受一个 view 的范围适配器。其产生的 view 的第 i 个元素(“窗口”)为一个 std::tuple,它保有原视图的从第 i 到第 i + N - 1N 个元素的引用。
S 为原视图的大小,那么生成的视图大小:
  • 如果 S >= N,则为 S - N + 1
  • 否则为 0,且结果视图为空。
2) 名字 views::adjacent<N> 代表一个范围适配器对象 (RangeAdaptorObject) 。给定子表达式 e 与常量表达式 N
  • 如果 N 等于 0decltype((e)) 实现 forward_range,则表达式 views::adjacent<N>(e) 表达式等价((void)e, auto(views::empty<tuple<>>))
  • 否则 views::adjacent<N>(e) 表达式等价于 adjacent_view<views::all_t<decltype((e))>, N>(e)
3) 名字 views::pairwise 代表一个范围适配器对象 (RangeAdaptorObject) ,其行为如同 views::adjacent<2>

adjacent_view 始终实现 forward_range,并且如果被适配的 view 实现 bidirectional_rangerandom_access_rangesized_range 则它也实现对应的概念。

数据成员

成员名称 定义
base_ (私有) V 类型的底层 view
(仅用于阐述的成员对象*)

成员函数

构造 adjacent_view
(公开成员函数)
返回指向起始的迭代器
(公开成员函数)
返回 指向末尾的迭代器或哨位
(公开成员函数)
返回元素数。仅当底层(适配的)范围满足 sized_range 时才提供。
(公开成员函数)
继承自 std::ranges::view_interface
返回视图是否为空。仅当视图满足 forward_range 时提供。
(std::ranges::view_interface<D> 的公开成员函数)
(C++23)
返回指向范围起始的常量迭代器。
(std::ranges::view_interface<D> 的公开成员函数)
(C++23)
返回对应于范围常量迭代器的哨位。
(std::ranges::view_interface<D> 的公开成员函数)
返回派生视图是否为非空。仅当 ranges::empty 可应用于它时提供。
(std::ranges::view_interface<D> 的公开成员函数)
返回派生视图中的首元素。仅当视图满足 forward_range 时提供。
(std::ranges::view_interface<D> 的公开成员函数)
返回派生视图中的末元素。仅当视图满足 bidirectional_rangecommon_range 时提供。
(std::ranges::view_interface<D> 的公开成员函数)
返回派生视图中的第 n 个元素。仅当视图满足 random_access_range 时提供。
(std::ranges::view_interface<D> 的公开成员函数)

推导指引

(无)

嵌套类

迭代器类型
(仅用于阐述的成员类模板*)
adjacent_viewcommon_range 时使用的哨位类型
(仅用于阐述的成员类模板*)

辅助模板

template< class V, size_t N >

constexpr bool ranges::enable_borrowed_range<adjacent_view<V, N>> =

    ranges::enable_borrowed_range<V>;
(C++23 起)

ranges::enable_borrowed_range 的特化使得底层视图满足 borrowed_range 时,adjacent_view 同样满足。

注解

views::adjacent 仅接受向前范围,即使当 N0

ranges::adjacent_viewranges::slide_view 有以下相似之处:

  • 两者都创建了大小为 N 的“滑窗”。
  • 两者大小同为 S - N + 1,其中 S 为所适配 view 的大小,使得 S >= N > 0

下面的表格展示这些适配器之间的区别:

视图适配器 value_type 窗口大小 N
ranges::adjacent_view std::tuple 模板形参
ranges::slide_view ranges::range 运行时实参
功能特性测试 标准 功能特性
__cpp_lib_ranges_zip 202110L (C++23) ranges::zip_view,
ranges::zip_transform_view,
ranges::adjacent_view,
ranges::adjacent_transform_view

示例

#include <array>
#include <format>
#include <iostream>
#include <ranges>
#include <tuple>
 
int main()
{
    constexpr std::array v{1, 2, 3, 4, 5, 6};
    std::cout << "v = [1 2 3 4 5 6]\n";
 
    for (int i{}; std::tuple t : v | std::views::adjacent<3>)
    {
        auto [t0, t1, t2] = t;
        std::cout << std::format("e = {:<{}}[{} {} {}]\n", "", 2 * i++, t0, t1, t2);
    }
}

输出:

v = [1 2 3 4 5 6]
e = [1 2 3]
e =   [2 3 4]
e =     [3 4 5]
e =       [4 5 6]

缺陷报告

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

缺陷报告 应用于 出版时的行为 正确行为
LWG 4098 C++23 views::adjacent<0> 曾接受仅输入的范围 使之拒绝

引用

  • C++23 标准(ISO/IEC 14882:2024):
  • 26.7.25 Adjacent view [range.adjacent]

参阅

由应用变换函数到被适配视图的相邻元素的结果组成的 view
(类模板) (范围适配器对象)
第 M 个元素是另一 view 从第 M 到第 (M + N - 1) 个元素的 view 构成的 view
(类模板) (范围适配器对象)
另一个视图元素的 N 大小不重叠的连续块组成的 view 的范围
(类模板) (范围适配器对象)
由另一 view 的元素每次前进 N 步所获得的 view
(类模板) (范围适配器对象)