std::ranges::views::iota, std::ranges::iota_view
在标头 <ranges> 定义
|
||
template<std::weakly_incrementable W, std::semiregular Bound = std::unreachable_sentinel_t> |
(1) | (C++20 起) |
namespace views { inline constexpr /* 未指定 */ iota = /* 未指定 */; |
(2) | (C++20 起) |
调用签名 |
||
template< class W > requires /* 见下文 */ |
(C++20 起) | |
template< class W, class Bound > requires /* 见下文 */ |
(C++20 起) | |
定制点对象
名字 views::iota
代表一个定制点对象,它是字面 semiregular
类类型的 const 函数对象。为说明目的,以 __iota_fn
表示它的类型的 cv 无限定版本。
__iota_fn
的所有实例均相等。在相同参数上调用类型 __iota_fn
的不同实例的效果是等价的,与指代该实例的表达式是左值还是右值,以及是否为 const 限定无关(然而不要求 volatile 限定的实例可调用)。从而能自由地复制 views::iota
并且能彼此替代地使用它的副本。
给定类型集合 Args...
,如果 std::declval<Args>()... 满足上面对于 views::iota
的参数要求,那么 __iota_fn
实现
- std::invocable<__iota_fn, Args...>、
- std::invocable<const __iota_fn, Args...>、
- std::invocable<__iota_fn&, Args...> 和
- std::invocable<const __iota_fn&, Args...>。
否则,__iota_fn
的函数调用运算符不会参与重载决议。
数据成员
iota_view
的典型实现保有量个非静态数据成员:类型是 W
的起始值 value_ 和类型是 Bound
的哨位值 bound_。此处显示的名字仅用于阐述。
成员函数
(构造函数) (C++20) |
创建 iota_view (公开成员函数) |
begin (C++20) |
获得 iota_view 的起始迭代器 (公开成员函数) |
end (C++20) |
获得指代 iota_view 末尾的哨位 (公开成员函数) |
size (C++20) |
在 iota_view 具有大小时获得它的大小 (公开成员函数) |
继承自 std::ranges::view_interface | |
(C++20) |
返回视图是否为空。若视图满足 forward_range 则提供。 ( std::ranges::view_interface<D> 的公开成员函数) |
(C++23) |
返回指向范围起始的常量迭代器。 ( std::ranges::view_interface<D> 的公开成员函数) |
(C++23) |
返回对应于范围常量迭代器的哨位。 ( std::ranges::view_interface<D> 的公开成员函数) |
(C++20) |
返回派生视图是否为非空。若 ranges::empty 可应用于它则提供。 ( std::ranges::view_interface<D> 的公开成员函数) |
(C++20) |
返回派生视图中的首元素。若视图满足 forward_range 则提供。 ( std::ranges::view_interface<D> 的公开成员函数) |
(C++20) |
返回派生视图中的末元素。若视图满足 bidirectional_range 与 common_range 则提供。 ( std::ranges::view_interface<D> 的公开成员函数) |
(C++20) |
返回派生视图中的第 n 个元素。若视图满足 random_access_range 则提供。 ( std::ranges::view_interface<D> 的公开成员函数) |
std::ranges::iota_view::iota_view
iota_view() requires std::default_initializable<W> = default; |
(1) | (C++20 起) |
constexpr explicit iota_view( W value ); |
(2) | (C++20 起) |
constexpr explicit iota_view( std::type_identity_t<W> value, std::type_identity_t<Bound> bound ); |
(3) | (C++20 起) |
constexpr explicit iota_view( /* iterator */ first, /* 见下文 */ last ); |
(4) | (C++20 起) |
iota_view
,例如 iota(0) 产生数 0、1、2 ……无穷大。iota_view
,例如 iota(10, 20) 产生从 10 到 19 的数。W
值初始化 value_,以及
- 如果
W
和Bound
是同一类型,那么 last 的类型是 /* iterator */,并且以在 last 存储的W
值初始化 bound_, - 否则,如果
iota_view
无界(即Bound
是 std::unreachable_sentinel_t),那么 last 的类型是 std::unreachable_sentinel_t,并且以 std::unreachable_sentinel 初始化 bound_。 - 否则 last 的类型是 /* sentinel */,并且以在 last 存储的
Bound
值初始化 bound_。
对于 (2)、(3) 和 (4),如果 iota_view
有界(即 Bound
不是 std::unreachable_sentinel_t)且 bound_ 被初始化为不可从 value_ 抵达的值,那么行为未定义。
参数
value | - | 起始值 |
bound | - | 边界 |
first | - | 指代起始值的迭代器 |
last | - | 指代边界的哨位 |
std::ranges::iota_view::end
constexpr auto end() const; |
(1) | (C++20 起) |
constexpr /* iterator */ end() const requires std::same_as<W, Bound>; |
(2) | (C++20 起) |
std::ranges::iota_view::size
|
(C++20 起) | |
在视图有界时返回视图的大小。
仅用于阐述的概念 advanceable
在此页面描述。
仅用于阐述的函数模板 'o-unsigned-like
将它的参数(必须是整数式)转换到参数类型的对应无符号版本。
推导指引
template< class W, class Bound > requires (!/* is-integer-like */<W> |
(C++20 起) | |
对于任何类型 T
,/* is-integer-like */<T> 当且仅当 T
是整数式类型时是 true,而 /* is-signed-integer-like */<T> 当且仅当 T
是整数式类型且能够表示负值时是 true。
注意推导指引自身会抵御有符号/无符号不匹配漏洞,如 views::iota(0, v.size()),其中 0 是 int(有符号)而 v.size() 是 std::size_t(无符号)。
嵌套类
(C++20) |
迭代器类型 (仅用于阐述的成员类*) |
(C++20) |
当 iota_view 有界且 Bound 与 W 不是同一类型时使用的哨位类型 (仅用于阐述的成员类*) |
辅助模板
template<std::weakly_incrementable W, std::semiregular Bound> inline constexpr bool enable_borrowed_range<ranges::iota_view<W, Bound>> = true; |
(C++20 起) | |
std::ranges::enable_borrowed_range 的此特化使得 iota_view
满足 borrowed_range
。
示例
#include <algorithm> #include <iostream> #include <ranges> struct Bound { int bound; bool operator==(int x) const { return x == bound; } }; int main() { for (int i : std::ranges::iota_view{1, 10}) std::cout << i << ' '; std::cout << '\n'; for (int i : std::views::iota(1, 10)) std::cout << i << ' '; std::cout << '\n'; for (int i : std::views::iota(1, Bound{10})) std::cout << i << ' '; std::cout << '\n'; for (int i : std::views::iota(1) | std::views::take(9)) std::cout << i << ' '; std::cout << '\n'; std::ranges::for_each(std::views::iota(1, 10), [](int i) { std::cout << i << ' '; }); std::cout << '\n'; }
输出:
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 3523 | C++20 | 迭代器-哨位对构造函数可能使用错误的哨位类型 | 已更正 |
LWG 3610 | C++20 | size 可能会拒绝整数类类型
|
使之在可能时接受 |
LWG 3714 (P2711R1) |
C++20 | 多参数构造函数不是显式的 | 改成显式的 |
P2325R3 | C++20 | iota_view 要求 W 是 semiregular 因为 view 要求 default_initializable
|
仅要求 W 是 copyable
|
参阅
(C++11) |
用从起始值开始连续递增的值填充一个范围 (函数模板) |