命名空间
变体
操作

std::ranges::views::single, std::ranges::single_view

来自 cppreference.cn
< cpp‎ | ranges
 
 
范围库 (Ranges library)
范围适配器 (Range adaptors)
 
定义于头文件 <ranges>
(1)
template< std::copy_constructible T >

    requires std::is_object_v<T>
class single_view

    : public ranges::view_interface<single_view<T>>
(C++20 起)
(直至 C++23)
template< std::move_constructible T >

    requires std::is_object_v<T>
class single_view

    : public ranges::view_interface<single_view<T>>
(C++23 起)
namespace views {

    inline constexpr /* unspecified */ single = /* unspecified */;

}
(2) (C++20 起)
调用签名 (Call signature)
template< class T >

    requires /* 见下文 */

constexpr /* see below */ single( T&& t );
(C++20 起)
1) 生成一个恰好包含一个指定值的 view
2) 对于任何合适的子表达式 e,表达式 views::single(e) 表达式等价于 single_view<std::decay_t<decltype((e))>>(e)

元素的生命周期绑定到父 single_view。复制 single_view 会复制元素。

目录

自定义点对象

名称 views::single 表示一个定制点对象,它是一个 const 函数对象,类型为 字面量 semiregular 类。为了便于说明,其类型的不带 cv 限定版本记作 __single_fn

__single_fn 的所有实例均相等。在相同实参上调用 __single_fn 类型的不同实例的效果是等价的,无论表示实例的表达式是左值还是右值,以及是否带 const 限定(然而,不要求 volatile 限定的实例是可调用的)。因此,views::single 可以自由复制,并且其副本可以互换使用。

给定一组类型 Args...,如果 std::declval<Args>()... 满足上述 views::single 的实参要求,则 __single_fn 遵循

否则,__single_fn 的任何函数调用运算符都不参与重载决议。

[编辑] 数据成员

成员 定义
copyable-box <T> value_ (直至 C++23) 视图的单个元素
(仅用于阐释的成员对象*)
movable-box <T> value_ (自 C++23 起) 视图的单个元素
(仅用于阐释的成员对象*)

[编辑] 成员函数

构造一个 single_view
(公开成员函数)
返回指向该元素的指针
(公开成员函数)
返回指向该元素之后的指针
(公开成员函数)
[静态]
返回 false
(公共静态成员函数)
[静态]
返回 1
(公共静态成员函数)
返回指向该元素的指针
(公开成员函数)
继承自 std::ranges::view_interface
(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::single_view::single_view

single_view() requires std::default_initializable<T> = default;
(1) (C++20 起)
(2)
constexpr explicit single_view( const T& t );
(C++20 起)
(直至 C++23)
constexpr explicit single_view( const T& t )
    requires std::copy_constructible<T>;
(C++23 起)
constexpr explicit single_view( T&& t );
(3) (C++20 起)
template< class... Args >

    requires std::constructible_from<T, Args...>

constexpr explicit single_view( std::in_place_t, Args&&... args );
(4) (C++20 起)

构造一个 single_view

1) 默认初始化 value_,它对所包含的值进行值初始化。
2)t 初始化 value_
3)std::move(t) 初始化 value_
4) 初始化 value_,如同通过 value_{std::in_place, std::forward<Args>(args)...}

std::ranges::single_view::begin

constexpr T* begin() noexcept;
constexpr const T* begin() const noexcept;
(C++20 起)

等价于 return data();

std::ranges::single_view::end

constexpr T* end() noexcept;
constexpr const T* end() const noexcept;
(C++20 起)

等价于 return data() + 1;

std::ranges::single_view::empty

static constexpr bool empty() noexcept;
(C++20 起)

等价于 return false;

std::ranges::single_view::size

static constexpr std::size_t size() noexcept;
(C++20 起)

等价于 return 1;

使 single_view 模拟 /*tiny-range*/,以满足 split_view 的要求。

std::ranges::single_view::data

constexpr T* data() noexcept;
constexpr const T* data() const noexcept;
(C++20 起)

返回指向 value_ 中所包含值的指针。如果 value_ 不包含值,则行为未定义。

[编辑] 推导指引

template< class T >
single_view( T ) -> single_view<T>;
(C++20 起)

[编辑] 注解

对于 single_view,继承的 empty 成员函数总是返回 false,并且继承的 operator bool 转换函数总是返回 true

[编辑] 示例

#include <iomanip>
#include <iostream>
#include <ranges>
#include <string>
#include <tuple>
 
int main()
{
    constexpr std::ranges::single_view sv1{3.1415}; // uses (const T&) constructor
    static_assert(sv1);
    static_assert(not sv1.empty());
 
    std::cout << "1) *sv1.data(): " << *sv1.data() << '\n'
              << "2) *sv1.begin(): " << *sv1.begin() << '\n'
              << "3)  sv1.size(): " << sv1.size() << '\n'
              << "4)  distance: " << std::distance(sv1.begin(), sv1.end()) << '\n';
 
    std::string str{"C++20"};
    std::cout << "5)  str = " << std::quoted(str) << '\n';
    std::ranges::single_view sv2{std::move(str)}; // uses (T&&) constructor
    std::cout << "6) *sv2.data(): " << std::quoted(*sv2.data()) << '\n'
              << "7)  str = " << std::quoted(str) << '\n';
 
    std::ranges::single_view<std::tuple<int, double, std::string>>
        sv3{std::in_place, 42, 3.14, "😄"}; // uses (std::in_place_t, Args&&... args)
 
    std::cout << "8)  sv3 holds a tuple: { "
              << std::get<0>(sv3[0]) << ", "
              << std::get<1>(sv3[0]) << ", "
              << std::get<2>(sv3[0]) << " }\n";
}

输出

1) *sv1.data(): 3.1415
2) *sv1.begin(): 3.1415
3)  sv1.size(): 1
4)  distance: 1
5)  str = "C++20"
6) *sv2.data(): "C++20"
7)  str = ""
8)  sv3 holds a tuple: { 42, 3.14, 😄 }

[编辑] 缺陷报告

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

缺陷报告 应用于 发布时的行为 正确的行为
LWG 3428 C++20 single_view 可从 std::in_place_t 转换 构造函数被显式化
LWG 4035 C++20 single_view 未提供成员函数 empty() 提供 empty()
P2367R0 C++20 single_view 的推导指引未能使实参衰变;
views::single 复制但未包装 single_view
提供了一个衰变指引;
使其始终包装

[编辑] 参见

(C++17)
可能包含或不包含对象的包装器
(类模板) [编辑]
一个不含元素的空 view
(类模板) (变量模板)[编辑]
一个 view,包含通过分隔符拆分另一个 view 获得的子范围
(类模板) (range adaptor object)[编辑]