std::ranges::views::take, std::ranges::take_view
来自cppreference.com
在标头 <ranges> 定义
|
||
template< ranges::view V > class take_view |
(1) | (C++20 起) |
namespace views { inline constexpr /* 未指定 */ take = /* 未指定 */; |
(2) | (C++20 起) |
调用签名 |
||
template< ranges::viewable_range R > requires /* 见下文 */ |
(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) 表达式等价于(其中 T
是 std::remove_cvref_t<decltype((e))>,而 D
是 ranges::range_difference_t<decltype((e))>):
- ((void)f,
T
是 ranges::empty_view,但 e 与 f 的求值顺序不确定; - U(ranges::begin(e), ranges::begin(e) + std::min<D>(ranges::distance(e), f)),如果
T
是 std::span、std::basic_string_view 或 ranges::subrange 的特化且它通杀实现random_access_range
和sized_range
,其中U
是
- std::span<typename T::element_type>,如果
T
是 std::span 的特化; -
T
,如果T
是 std::basic_string_view 的特化; - ranges::subrange<ranges::iterator_t<T>>,如果
T
是 ranges::subrange 的特化;
- std::span<typename T::element_type>,如果
- ranges::iota_view(*ranges::begin(e),
*(ranges::begin(e) + std::min<D>(ranges::distance(e), f))),如果T
是 ranges::iota_view 的特化且同时实现random_access_range
和sized_range
;
|
(C++23 起) |
- 否则是 take_view(e, f)。
当底层视图 V
实现概念 contiguous_range
、random_access_range
、bidirectional_range
、forward_range
、input_range
及 sized_range
时,take_view 实现相应的概念。当底层视图 V
同时实现 sized_range
和 random_access_range
时,它实现 common_range
。
数据成员
成员名称 | 定义 |
base_ (私有)
|
V 类型的底层概念 view (仅用于阐述的成员对象*) |
count_ (私有)
|
要取得的元素数量,ranges::range_difference_t<V> 类型 (仅用于阐述的成员对象*) |
成员函数
构造 take_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> 的公开成员函数) | |
返回派生视图的数据的地址。若视图的迭代器类型满足 contiguous_iterator 则提供。 ( std::ranges::view_interface<D> 的公开成员函数) | |
返回派生视图中的首元素。仅当视图满足 forward_range 时提供。 ( std::ranges::view_interface<D> 的公开成员函数) | |
返回派生视图中的末元素。仅当视图满足 bidirectional_range 与 common_range 时提供。 ( std::ranges::view_interface<D> 的公开成员函数) | |
返回派生视图中的第 n 个元素。仅当视图满足 random_access_range 时提供。 ( std::ranges::view_interface<D> 的公开成员函数) |
推导指引
嵌套类
(C++20) |
哨位类型 (仅用于阐述的成员类模板*) |
辅助模板
template< class T > constexpr bool enable_borrowed_range<std::ranges::take_view<T>> = |
(C++20 起) | |
std::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 的情况下是
|
参阅
(C++20) |
从迭代器和计数创建子范围 (定制点对象) |
由另一 view 的到首个谓词返回 false 为止的起始元素组成的 view (类模板) (范围适配器对象) | |
(C++20) |
将一定数目的元素复制到一个新的位置 (niebloid) |