std::ranges::views::filter, std::ranges::filter_view
来自cppreference.com
在标头 <ranges> 定义
|
||
template< ranges::input_range V, std::indirect_unary_predicate<ranges::iterator_t<V>> Pred > |
(1) | (C++20 起) |
namespace views { inline constexpr /* 未指定 */ filter = /* 未指定 */; |
(2) | (C++20 起) |
调用签名 |
||
template< ranges::viewable_range R, class Pred > requires /* 见下文 */ |
(C++20 起) | |
template< class Pred > constexpr /* 范围适配器闭包 */ filter( Pred&& pred ); |
(C++20 起) | |
1) 表示排除了不能满足谓词的元素的底层序列的
view
的范围适配器。filter_view
在底层 view
V
实现 bidirectional_range
、 forward_range
、 input_range
及 common_range
时分别实现相应的概念。
数据成员
filter_view
的典型实现保有两个或三个数据成员:
-
V
类型的底层view
(此处以base_
表示,仅用于阐述), - /* copyable-box */<Pred> 类型的包装,包装用于滤出
base_
的元素的谓词(此处以pred_
表示,仅用于阐述),其中 copyable-box 是始终满足copyable
的包装类模板, - std::optional 式对象(此处以
begin_
表示,仅用于阐述),缓存指向base_
的首个满足pred_
的元素的迭代器。begin_
只有在filter_view
实现forward_range
才可能存在。
成员函数
(构造函数) (C++20) |
构造 filter_view (公开成员函数) |
base (C++20) |
返回底层视图 V (公开成员函数) |
pred (C++20) |
返回到存储于 filter_view 内的谓词的引用 (公开成员函数) |
begin (C++20) |
返回 filter_view 的起始迭代器 (公开成员函数) |
end (C++20) |
返回 filter_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> 的公开成员函数) |
std::ranges::filter_view::filter_view
filter_view() requires std::default_initializable<V> && std::default_initializable<Pred> = default; |
(1) | (C++20 起) |
constexpr explicit filter_view( V base, Pred pred ); |
(2) | (C++20 起) |
1) 经由默认成员初始化器(= V())值初始化
base_
,并默认初始化 pred_
(这会值初始化它包含的 Pred
)。2) 以 std::move(base) 初始化
base_
并以 std::move(pred) 初始化 pred_
。参数
base | - | 要过滤的范围 |
pred | - | 滤出元素的谓词 |
std::ranges::filter_view::base
constexpr V base() const& requires std::copy_constructible<V>; |
(1) | (C++20 起) |
constexpr V base() &&; |
(2) | (C++20 起) |
1) 等价于 return base_;。
2) 等价于 return std::move(base_);。
std::ranges::filter_view::pred
constexpr const Pred& pred() const; |
(C++20 起) | |
返回到存储的 Pred
对象的引用。如果 pred_
没有包含值,那么行为未定义。
std::ranges::filter_view::begin
constexpr /* iterator */ begin(); |
(C++20 起) | |
为提供 range
概念所要求的均摊常数时间复杂度,此函数在 filter_view
对象内存储结果以用于后继调用。等价于
if constexpr (!ranges::forward_range<V>) return /* iterator */{*this, ranges::find_if(base_, std::ref(*pred_))}; else { if (!begin_.has_value()) begin_ = ranges::find_if(base_, std::ref(*pred_)); // 缓存 return /* iterator */{*this, begin_.value())}; }
如果 pred_
没有包含值,那么行为未定义。
std::ranges::filter_view::end
constexpr auto end() { |
(C++20 起) | |
推导指引
template< class R, class Pred > filter_view( R&&, Pred ) -> filter_view<views::all_t<R>, Pred>; |
(C++20 起) | |
嵌套类
(C++20) |
filter_view 的迭代器类型 (仅用于阐述的成员类*) |
(C++20) |
底层视图非 common_range 时的 filter_view 的哨位类型 (仅用于阐述的成员类*) |
示例
运行此代码
#include <iostream> #include <ranges> int main() { auto even = [](int i){ return 0 == i % 2; }; auto square = [](int i){ return i * i; }; for (int i : std::views::iota(0, 6) | std::views::filter(even) | std::views::transform(square)) std::cout << i << ' '; }
输出:
0 4 16
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 3714 (P2711R1) |
C++20 | 多参数构造函数不是显式的 | 改成显式的 |
P2325R3 | C++20 | 如果 Pred 不 default_initializable ,那么默认构造函数构造不含 Pred 的 filter_view
|
filter_view 也不default_initializable
|
参阅
由另一 view 的到首个谓词返回 false 为止的起始元素组成的 view (类模板) (范围适配器对象) |