命名空间
变体
操作

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

来自 cppreference.com
< cpp‎ | ranges
 
 
范围库
范围适配器
 
在头文件 <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 起)
调用签名
template< class T >

    requires /* see below */

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

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

内容

自定义点对象

名称 views::single 表示一个自定义点对象,它是一个常量 函数对象,类型为一个 字面量 semiregular 类类型。出于说明目的,其类型的 cv 无限定版本表示为 __single_fn

所有 __single_fn 实例都是相等的。无论表示实例的表达式是左值还是右值,以及是否为 const 限定,调用 __single_fn 类型不同实例对相同参数的效果都是等价的(但是,不保证可以调用 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++ 标准。

DR 应用于 发布的行为 正确的行为
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
(类模板) (范围适配器对象)[编辑]