std::ranges::views::filter, std::ranges::filter_view

< cpp‎ | ranges
template< ranges::input_range V,

          std::indirect_unary_predicate<ranges::iterator_t<V>> Pred >
    requires ranges::view<V> && std::is_object_v<Pred>

class filter_view : public ranges::view_interface<filter_view<V, Pred>>
(1) (C++20 起)
namespace views {

    inline constexpr /*unspecified*/ filter = /*unspecified*/;

}
(2) (C++20 起)
1) 表示底层序列去掉不满足谓词的元素后的 view 的范围适配器。
2) 对于任何适合的子表达式 EP 表达式 views::filter(E, P) 表达式等价filter_view{E, P}

当底层范围 V 实现 bidirectional_rangeforward_rangeinput_rangecommon_range 时, filter_view 分别实现对应的概念。

表达式等价

表达式 e 表达式等价于表达式 f ,若 ef 拥有相同效果,均为潜在抛出或均非潜在抛出(即 noexcept(e) == noexcept(f) ),且均为常量子表达式或均非常量子表达式。

数据成员

std::ranges::filter_view::base_

V base_ = V(); /* exposition-only */

底层视图。

std::ranges::filter_view::pred_

semiregular_box<Pred> pred_; /* exposition-only */

滤出 base_ 的元素所用的谓词。

semiregular_box 是除一些小差异外,表现恰如 std::optional 的包装类模板。名称 semiregular_box 仅为说明目的而非规范性的。

成员函数

(构造函数)
构造 filter_view
(公开成员函数)
base
返回底层视图 V
(公开成员函数)
beginend
返回指向范围元素的迭代器或哨位
(公开成员函数)

std::ranges::filter_view::filter_view

filter_view() = default;
(1)
constexpr filter_view(V base, Pred pred);
(2)
template<ranges::input_range R>

    requires
        ranges::viewable_range<R> && std::constructible_from<V, views::all_t<R>>

constexpr filter_view(R&& r, Pred pred);
(3)
1) 默认初始化 base_pred_
2)std::move(base) 初始化 base_ 并以 std::move(pred) 初始化 pred
3)views::all(std::forward<R>(r)) 初始化 base_ 并以 std::​move(pred) 初始化 pred_

参数

r - 要过滤的范围
pred - 滤出元素的谓词

std::ranges::filter_view::base

constexpr V base() const;

等价于 return base_;

std::ranges::filter_view::begin

constexpr iterator begin();

返回以 {*this, ranges::find_if(base_, std::ref(*pred_))} 初始化的迭代器。为提供 range 概念所要求的均摊常数时间复杂度,此函数在 filter_view 对象内为后继调用上的使用缓存结果。

行为未定义,除非 pred_.has_value()

std::ranges::filter_view::end

等价于

constexpr auto end() {

  if constexpr (ranges::common_range<V>)
    return iterator{*this, ranges::end(base_)};
  else
    return sentinel{*this};

}

推导指引

template<class R, class Pred>
filter_view(R&&, Pred) -> filter_view<views::all_t<R>, Pred>;

嵌套类

std::ranges::filter_view::iterator

template<class V, class Pred>
class filter_view<V, Pred>::iterator /* exposition-only */

filter_view::begin 的返回类型。

V 实现 bidirectional_range 则为 bidirectional_iterator ,若 V 实现 forward_range 则为 forward_iterator ,否则为 input_iterator

容许修改此迭代器所代表的元素,但若结果值不满足滤的谓词则导致未定义行为。

成员类型

 
成员类型 定义
iterator_concept 如对应迭代器概念所要求
iterator_category 如对应迭代器概念所要求
value_type std::range_value_t<V>
difference_type std::range_difference_t<V>

成员类型

(构造函数)
构造迭代器
(公开成员函数)
base
返回底层迭代器
(公开成员函数)
operator*operator->
转发到底层迭代器
(公开成员函数)
operator++operator++(int)operator--operator--(int)
前进或减少迭代器
(公开成员函数)

非成员函数

operator==iter_moveiter_swap
转发到底层迭代器
(公开成员函数)

std::ranges::filter_view::iterator::iterator

iterator() = default;
constexpr iterator(filter_view& parent, ranges::iterator_t<V> current);

current 初始化仅为说明的数据成员 current_ ,以 std::addressof(parent) 初始化仅为说明的数据成员 parent_

std::ranges::filter_view::iterator::operator++

constexpr iterator& operator++()

等价于

current_ = ranges::find_if(++current_, ranges::end(parent_->base_), ref(*parent_->pred_));
return *this;

std::ranges::filter_view::iterator::operator--

constexpr iterator& operator--() requires ranges::bidirectional_range<V>;

等价于

do
  --current_;
while (!invoke(*parent_->pred_, *current_));
return *this;

其他作为迭代器应有的成员。

std::ranges::filter_view::sentinel

template<class V, class Pred>
class filter_view<V, Pred>::sentinel /* exposition-only */

filter_view::end 的返回类型。

成员函数

(构造函数)
构造哨位
(公开成员函数)
base
返回底层迭代器
(公开成员函数)

非成员函数

operator==
比较底层迭代器与底层哨位
(公开成员函数)

std::ranges::filter_view::sentinel::end_

ranges::sentinel_t<V> end_ = ranges::sentinel_t<V>(); /* exposition only */

保有底层 view 的哨位的仅为说明的数据成员。

std::ranges::filter_view::sentinel::sentinel

sentinel() = default;
constexpr explicit sentinel(filter_view& parent);

parent 初始仅为说明的数据成员 end_

std::ranges::filter_view::sentinel::base

constexpr ranges::sentinel_t<V> base() const;

等价于: return end_;

std::ranges::filter_view::sentinel::operator==

friend constexpr bool operator==(const iterator& x, const sentinel& y);

等价于: return x.current_ == y.end_;

示例

#include <vector>
#include <ranges>
#include <iostream>
 
int main()
{
    std::vector<int> ints{0,1,2,3,4,5};
    auto even = [](int i){ return 0 == i % 2; };
    auto square = [](int i) { return i * i; };
 
    for (int i : ints | std::views::filter(even) | std::views::transform(square)) {
        std::cout << i << ' ';
    }
}

输出:

0 4 16