std::ranges::views::take, std::ranges::take_view

来自cppreference.com
 
 
范围库
范围适配器
 
 
<tbody> </tbody>
在标头 <ranges> 定义
template< ranges::view V > class take_view : public ranges::view_interface<take_view<V>>
(1) (C++20 起)
namespace views { inline constexpr /* 未指定 */ take = /* 未指定 */; }
(2) (C++20 起)
调用签名
template< ranges::viewable_range R > requires /* 见下文 */ constexpr ranges::view auto take( R&& r, ranges::range_difference_t<R> count );
(C++20 起)
template< class DifferenceType > constexpr /* 范围适配器闭包 */ take( DifferenceType&& count );
(C++20 起)
1) 范围适配器,表示来自底层序列中始于开端终于给定边界的元素的 view
2) views::take 是一个范围适配器对象 (RangeAdaptorObject) 。表达式 views::take(e, f) 产生表示来自 e 的前 f 个元素的视图。结果不一定是 take_view

views::take(e, f) 表达式等价于(其中 Tstd::remove_cvref_t<decltype((e))>,而 Dranges::range_difference_t<decltype((e))>):

  • ((void)f, decay-copy(e)),如果 Tranges::empty_view,但 ef 的求值顺序不确定;
  • U(ranges::begin(e), ranges::begin(e) + std::min<D>(ranges::distance(e), f)),如果 Tstd::spanstd::basic_string_viewranges::subrange 的特化且它同时实现 random_access_rangesized_range,其中 U
  • std::span<typename T::element_type>,如果 Tstd::span 的特化;
  • T,如果 Tstd::basic_string_view 的特化;
  • ranges::subrange<ranges::iterator_t<T>>,如果 Tranges::subrange 的特化;
  • ranges::iota_view(*ranges::begin(e),
    *(ranges::begin(e) + std::min<D>(ranges::distance(e), f)))
    ,如果 Tranges::iota_view 的特化且同时实现 random_access_rangesized_range
  • views::repeat(*e.value_, std::min<D>(ranges::distance(e), f)),如果 T 实现 sized_range;这种情况下 e 仅求值一次;
  • 否则是 views::repeat(*e.value_, static_cast<D>(e))
(C++23 起)
  • 否则是 take_view(e, f)

所有情况下 decltype((f)) 必须实现 std::convertible_to<D>

当底层视图 V 实现概念 contiguous_rangerandom_access_rangebidirectional_rangeforward_rangeinput_rangesized_range 时,take_view 实现相应的概念。当底层视图 V 同时实现 sized_rangerandom_access_range 时,它实现 common_range

数据成员

成员 说明
V base_ 底层视图
(仅用于阐述的成员对象*)
ranges::range_difference_t<V> count_ 要取得的元素数量
(仅用于阐述的成员对象*)

成员函数

构造 take_view
(公开成员函数) [编辑]
返回底层(适配的)视图的副本
(公开成员函数) [编辑]
返回指向起始的迭代器
(公开成员函数) [编辑]
返回 指向末尾的迭代器或哨位
(公开成员函数) [编辑]
返回元素数,仅当底层(适配的)范围满足 sized_range 时才提供
(公开成员函数) [编辑]
返回结果 approximately_sized_range 的估计大小
(公开成员函数) [编辑]
继承自 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> 的公开成员函数) [编辑]
返回派生视图的数据的地址,仅当视图的迭代器类型满足 contiguous_iterator 时提供
(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> 的公开成员函数) [编辑]

推导指引

嵌套类

(C++20)
哨位类型
(仅用于阐述的成员类模板*)

辅助模板

<tbody> </tbody>
template< class T > constexpr bool enable_borrowed_range<std::ranges::take_view<T>> = ranges::enable_borrowed_range<T>;
(C++20 起)

ranges::enable_borrowed_range 的此特化使得 take_view 在底层类型实现 borrowed_range 时实现它。

示例

#include <algorithm>
#include <iostream>
#include <ranges>

int main()
{
    namespace views = std::views;
    auto print = [](char x){ std::cout << x; };

    for (const char nums[]{'1', '2', '3'};
         int n : views::iota(0, 5))
    {
        std::cout << "take(" << n << "): ";
        // 安全地只获取至 min(n, nums.size()) 个元素:
        std::ranges::for_each(nums | views::take(n), print);
        std::cout << '\n';
    }
}

输出:

take(0): 
take(1): 1
take(2): 12
take(3): 123
take(4): 123

缺陷报告

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

缺陷报告 应用于 出版时的行为 正确行为
LWG 3407 C++20 views::take 有时无法构造具大小随机访问范围 调整结果类型使构造始终合法
LWG 3494 C++20 take_view 决不是 borrowed_range 在底层视图是 borrowed_range 的情况下是

参阅

从迭代器和计数创建子范围
(定制点对象) [编辑]
由另一 view 的到首个谓词返回 false 为止的起始元素组成的 view
(类模板) (范围适配器对象) [编辑]
复制若干元素到新位置
(算法函数对象) [编辑]