命名空间
变体
操作

可赋值包装器 (C++20)

来自 cppreference.cn
< cpp‎ | ranges
 
 
范围库
范围适配器
辅助项
copyable-box
movable-box
(直到 C++23)  (C++23 起)


 
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(/* 见下方 */);
(自 C++20 起)
(直到 C++23)
constexpr /*movable-box*/& operator=(const /*movable-box*/& other);
    noexcept(/* 见下方 */) 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,因为始终提供默认构造函数(这可能会构造一个无值的包装器)。

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

[编辑] 缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
P2325R3 C++20 如果 T 不是 default_initializable,则默认构造函数
构造不含值的包装器
该包装器也
不是 default_initializable
LWG 3572 C++20 有条件地不同的赋值运算符不是 constexpr 设为 constexpr

[编辑] 参见

一个 view,其中包含指定值的单个元素
(类模板) (自定义点对象)[编辑]
一个 view,由通过重复生成相同值而生成的序列组成
(类模板) (自定义点对象)[编辑]
一个 view,由满足谓词的 range 的元素组成
(类模板) (范围适配器对象)[编辑]
一个序列的 view,它将变换函数应用于每个元素
(类模板) (范围适配器对象)[编辑]
一个 view,由另一个 view 的初始元素组成,直到谓词返回 false 的第一个元素
(类模板) (范围适配器对象)[编辑]
一个 view,由另一个 view 的元素组成,跳过初始元素的子序列,直到谓词返回 false 的第一个元素
(类模板) (范围适配器对象)[编辑]
一个 view,由对适配视图的对应元素应用变换函数的结果组成
(类模板) (自定义点对象)[编辑]
一个 view,由对适配视图的相邻元素应用变换函数的结果组成
(类模板) (范围适配器对象)[编辑]