可赋值包装 (C++20)

来自cppreference.com
< cpp‎ | ranges
 
 
范围库
范围访问
范围转换器
(C++23)
范围原语



悬垂迭代器处理
范围概念
视图

范围工厂
适配器
范围生成器
范围适配器对象
范围适配器闭包对象
辅助项
copyable-box
 
template<class T>

    requires std::copy_constructible<T> && std::is_object_v<T>

class /*copyable-box*/;
(C++20 起)
(C++23 前)
template<class T>

    requires std::move_constructible<T> && std::is_object_v<T>

class /*movable-box*/;
(C++23 起)

ranges::single_viewranges::repeat_view (C++23 起) 以及存储一个可调用对象的范围适配器通过仅用于阐释的类模板 copyable-box (C++23 前)movable-box (C++23 起) 说明。此处显示的名字仅用于阐释目的。

该包装行为准确地与 std::optional<T> 相同,除了默认构造函数、复制赋值运算符与移动赋值运算符(条件性地)异于 std::optional 。这在需要时为 T 增设赋值能力,并使得包装始终满足 copyablemovable (C++23 起)

T 已为 copyable ,或 std::is_nothrow_move_constructible_v<T>std::is_nothrow_copy_constructible_v<T> 均为 true ,则 /*copyable-box*/<T> 可以只存储一个 T 对象,因为它始终含值。

(C++23 前)

T

/*movable-box*/<T> 可以仅存储一个 T 对象,因为它始终含值。

(C++23 起)

模板形参

T - 被含有值的类型,必须为实现 copy_constructible (C++23 前)move_constructible (C++23 起) 的对象类型

成员函数

默认构造函数

constexpr /*copyable-box*/() noexcept(std::is_nothrow_default_constructible_v<T>)

    requires std::default_initializable<T>

    : /*copyable-box*/(std::in_place) { }
(C++20 起)
(C++23 前)
constexpr /*movable-box*/() noexcept(std::is_nothrow_default_constructible_v<T>)

    requires std::default_initializable<T>

    : /*movable-box*/(std::in_place) { }
(C++23 起)

当且仅当 T 实现 default_initializable 才提供默认构造函数。

默认构造的包装含有值初始化的 T 对象。

赋值运算符

(1)
constexpr /*copyable-box*/& operator=(const /*copyable-box*/& other);
    noexcept(/* see below */);
(C++20 起)
(C++23 前)
constexpr /*movable-box*/& operator=(const /*movable-box*/& other);
    noexcept(/* see below */) requires std::copy_constructible<T>;
(C++23 起)
(2)
constexpr /*copyable-box*/& operator=(/*copyable-box*/&& other)
    noexcept(std::is_nothrow_move_constructible_v<T>);
(C++20 起)
(C++23 前)
constexpr /*movable-box*/& operator=(/*movable-box*/&& other)
    noexcept(std::is_nothrow_move_constructible_v<T>);
(C++23 起)
1)std::copyable<T> 未得到实现,则复制赋值运算符等价地定义为:

constexpr /*copyable-box*/& operator=(const /*copyable-box*/& other)
    noexcept(std::is_nothrow_copy_constructible_v<T>)
{
    if (this != std::addressof(other)) {
        if (other) emplace(*other);
        else reset();
    }
    return *this;
}

(C++23 前)

constexpr /*movable-box*/& operator=(const /*movable-box*/& other)
    noexcept(std::is_nothrow_copy_constructible_v<T>)
    requires std::copy_constructible<T>
{
    if (this != std::addressof(other)) {
        if (other) emplace(*other);
        else reset();
    }
    return *this;
}

(C++23 起)
否则,它等同于 std::optional 的复制赋值运算符
2)std::movable<T> 未得到实现,则移动赋值运算符等价地定义为:

constexpr /*copyable-box*/& operator=(/*copyable-box*/&& other)
    noexcept(std::is_nothrow_move_constructible_v<T>)
{
    if (this != std::addressof(other)) {
        if (other) emplace(std::move(*other));
        else reset();
    }
    return *this;
}

(C++23 前)

constexpr /*movable-box*/& operator=(/*movable-box*/&& other)
    noexcept(std::is_nothrow_move_constructible_v<T>)
{
    if (this != std::addressof(other)) {
        if (other) emplace(std::move(*other));
        else reset();
    }
    return *this;
}

(C++23 起)
否则,它等同于 std::optional 的移动赋值运算符

等同于 std::optional 的成员

成员函数

构造 optional 对象
(std::optional<T> 的公开成员函数)
销毁容纳的值(如果存在)
(std::optional<T> 的公开成员函数)
对内容赋值
(std::optional<T> 的公开成员函数)
观察器
访问所含值
(std::optional<T> 的公开成员函数)
检查对象是否含值
(std::optional<T> 的公开成员函数)
修改器
销毁任何所含值
(std::optional<T> 的公开成员函数)
原位构造所含值
(std::optional<T> 的公开成员函数)

注解

若下列条件成立 copyable-box (C++23 前)movable-box (C++23 起) 则不含值,若

  • T 不实现 movablecopyable ,而分别在移动赋值或复制赋值时抛异常,或者
  • 从另一不含值的包装初始化/赋值它。

P2325R3 前,该包装在标准中被称为 semiregular-box ,并且始终满足 semiregular ,因为始终提供默认构造函数(可能构造无值的包装)。

功能特性测试 标准 注释
__cpp_lib_ranges 201911L (C++20) 范围库受约束算法
202106L (C++20)
(DR)
可默认初始化视图
202207L (C++23) 放松范围适配器以允许仅移动类型

缺陷报告

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

缺陷报告 应用于 出版时的行为 正确行为
P2325R3 C++20 Tdefault_initializable 则默认构造函数构造不含值的包装 包装亦非 default_initializable
LWG 3572 C++20 条件性有别的赋值运算符不是 constexpr 使之为 constexpr

参阅

含有具有指定值的单个元素的 view
(类模板) (定制点对象)
由重复产出同一值生成的序列组成的 view
(类模板) (定制点对象)
range 中满足某个谓词的元素构成的 view
(类模板) (范围适配器对象)
对序列的每个元素应用某个变换函数的 view
(类模板) (范围适配器对象)
由另一 view 的到首个谓词返回 false 为止的起始元素组成的 view
(类模板) (范围适配器对象)
由另一 view 跳过元素的起始序列,直至首个谓词返回 false 的元素组成的 view
(类模板) (范围适配器对象)
由应用变换函数到被适配视图的对应元素的结果的元组组成的 view
(类模板) (定制点对象)
由应用变换函数到被适配视图的相邻元素的结果的元组组成的 view
(类模板) (范围适配器对象)