std::ranges::views::repeat, std::ranges::repeat_view

来自cppreference.com
< cpp‎ | ranges
 
 
范围库
范围适配器
 
 
在标头 <ranges> 定义
template< std::move_constructible W,

          std::semiregular Bound = std::unreachable_sentinel_t >
    requires (std::is_object_v<W> && std::same_as<W, std::remove_cv_t<W>> &&
             (/*is-integer-like*/<Bound> ||
              std::same_as<Bound, std::unreachable_sentinel_t>))

class repeat_view : public ranges::view_interface<repeat_view<W, Bound>>
(1) (C++23 起)
namespace views {

    inline constexpr /* 未指定 */ repeat = /* 未指定 */;

}
(2) (C++23 起)
调用签名
template< class W >

    requires /* 见下文 */

constexpr /* 见下文 */ repeat( W&& value );
(C++23 起)
template< class W, class Bound >

    requires /* 见下文 */

constexpr /* 见下文 */ repeat( W&& value, Bound&& bound );
(C++23 起)
1) 通过重复产生相同的值来生成一系列元素的范围工厂。可以是有界或无界(无限)。
2) 对于任何合适的子表达式 efviews::repeat(e)views::repeat(e, f)表达式等价(有相同效果)于 repeat_view<std::decay_t<decltype((E))>>(e)repeat_view(e, f)

repeat_view 实现 random_access_range。如果 Bound 不是 std::unreachable_sentinel_t,那么 repeat_view 会实现 sized_rangecommon_range

定制点对象

名字 views::repeat 代表一个定制点对象,它是某个字面 semiregular 类类型的 const 函数对象。为阐述目的,以 __repeat_fn 表示它的类型的 cv 无限定版本。

__repeat_fn 的所有实例均相等。在相同实参上调用 __repeat_fn 类型的不同实例的效果是等价的,这与指代该实例的表达式是左值还是右值,以及是否为 const 限定无关(然而不要求 volatile 限定的实例是可调用的)。由此,可以自由地复制 views::repeat 并且能彼此替代地使用它的副本。

给定类型集合 Args...,如果 std::declval<Args>()... 满足上面对于 views::repeat 的实参的要求,那么 __repeat_fn 就实现

否则,__repeat_fn 的函数调用运算符不会参与重载决议。

数据成员

成员名 定义
value_ (私有) 包装类型 movable-box<W> 的起始值。
(仅用于阐述的成员对象*)
bound_ (私有) Bound 类型的哨位值。
(仅用于阐述的成员对象*)

成员函数

创建一个 repeat_view
(公开成员函数)
获取 repeat_view 的起始迭代器
(公开成员函数)
获取代表 repeat_view 末尾的哨位
(公开成员函数)
如果有边界,获取 repeat_view 的大小
(公开成员函数)
继承自 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> 的公开成员函数)
返回派生视图中的首元素。仅当视图满足 forward_range 时提供。
(std::ranges::view_interface<D> 的公开成员函数)
返回派生视图中的末元素。仅当视图满足 bidirectional_rangecommon_range 时提供。
(std::ranges::view_interface<D> 的公开成员函数)
返回派生视图中的第 n 个元素。仅当视图满足 random_access_range 时提供。
(std::ranges::view_interface<D> 的公开成员函数)

std::ranges::repeat_view::repeat_view

repeat_view() requires std::default_initializable<W> = default;
(1) (C++23 起)
constexpr explicit repeat_view( const W& value, Bound bound = Bound() );
(2) (C++23 起)
constexpr explicit repeat_view( W&& value, Bound bound = Bound() );
(3) (C++23 起)
template < class... WArgs, class... BoundArgs >

    requires std::constructible_from<W, WArgs...>
          && std::constructible_from<Bound, BoundArgs...>
constexpr explicit
    repeat( std::piecewise_construct_t, std::tuple<WArgs...> value_args,

            std::tuple<BoundArgs...> bound_args = std::tuple<>{} );
(4) (C++23 起)
1) 通过 value_bound_ 的默认成员初始化式(== W()= Bound()),对 value_bound_ 进行值初始化。
2)value 初始化 value_ 并以 bound 初始化 bound_。如果 Bound 不是 std::unreachable_sentinel_tbool(bound >= 0)false,那么行为未定义。
3)std::move(value)} 初始化 value_,并以 bound 初始化 bound_。如果Bound 不是 std::unreachable_sentinel_t,且 bool(bound >= 0)false,那么行为未定义。
4) 通过逐段构造来初始化 value_bound_

参数

value - 重复产生的值
bound - 边界

std::ranges::repeat_view::begin

constexpr /*iterator*/ begin() const;
(C++23 起)

返回一个以 std::addressof(*value_) 初始化的迭代器

std::ranges::repeat_view::end

constexpr /*iterator*/ end() const
    requires (!std::same_as<Bound, std::unreachable_sentinel_t>);
(1) (C++23 起)
constexpr std::unreachable_sentinel_t end() const;
(2) (C++23 起)
1) 返回以 std::addressof(*value_)} 和 bound_ 初始化的迭代器
2) 返回一个 std::unreachable_sentinel

std::ranges::repeat_view::size

constexpr auto size() const
    requires (!std::same_as<Bound, std::unreachable_sentinel_t>);
(C++23 起)

如果视图有边界,返回视图的大小。等价于 return /*to-unsigned-like*/(bound_);

仅用于参数的函数模板 to-unsigned-like 会将它的实参(必须是整数式类型)转换到实参类型的相应无符号版本。

推导指引

template< class W, class Bound = std::unreachable_sentinel_t >
repeat_view( W, Bound = Bound() ) -> repeat_view<W, Bound>;
(C++23 起)

嵌套类

迭代器类型
(仅用于阐述的成员类*)

注解

功能特性测试 标准 功能特性
__cpp_lib_ranges_repeat 202207L (C++23) std::ranges::repeat_view

示例

#include <iostream>
#include <ranges>
#include <string_view>
using namespace std::literals;
 
int main()
{
    // 有边界的重载
    for (auto s: std::views::repeat("C++"sv, 3))
        std::cout << s << ' ';
    std::cout << '\n';
 
    // 无边界的重载
    for (auto s : std::views::repeat("我知道你知道的是"sv)
                | std::views::take(3))
        std::cout << s << ' ';
    std::cout << "...\n";
}

输出:

C++ C++ C++
我知道你知道的是我知道你知道的是我知道你知道的是 ...

缺陷报告

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

缺陷报告 应用于 出版时的行为 正确行为
LWG 4053 C++20 views::repeat 的单实参调用不会退化实参 会退化实参
LWG 4054 C++20 repeat_view 调用 views::repeat 不会创建嵌套的 repeat_view 会创建嵌套的 repeat_view

参阅

由通过重复对某个初值自增所生成的序列组成的 view
(类模板) (定制点对象)