Namespaces
Variants

Assignable wrapper (C++20)

From cppreference.net
Ranges library
Range adaptors
Helper items
copyable-box
movable-box
(until 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_view , ranges::repeat_view , (C++23 起) 以及存储可调用对象的范围适配器,均通过一个仅用于说明的类模板 copyable-box (C++23 前) movable-box (C++23 起) 来定义。此处显示的名称仅用于说明目的。

该包装器的行为与 std:: optional < T > 完全一致,但其默认构造函数、拷贝赋值运算符和移动赋值运算符(有条件地)与 std::optional 有所不同——这些差异会在需要时为类型 T 增强可赋值性,并使其始终满足 copyable movable (自 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 ;
}

<span class="t-mark-re

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 不满足 movable copyable 概念要求,且在移动赋值或复制赋值时抛出异常,或
  • 它从另一个无值包装器进行初始化/赋值。

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

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

缺陷报告

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

缺陷报告 应用于 发布时的行为 正确行为
P2325R3 C++20 T 不满足 default_initializable ,默认构造函数
会构造一个不包含值的包装器
该包装器同样
不满足 default_initializable
LWG 3572 C++20 条件性不同的赋值运算符未声明为 constexpr 已改为 constexpr

参见

包含指定值的单个元素的 view
(类模板) (定制点对象)
通过重复生成相同值构成的 view
(类模板) (定制点对象)
由满足谓词的 range 元素组成的 view
(类模板) (范围适配器对象)
对序列中每个元素应用转换函数的 view
(类模板) (范围适配器对象)
包含另一个 view 的初始元素(直到谓词首次返回 false 的元素)的 view
(类模板) (范围适配器对象)
包含另一个 view 的元素(跳过初始子序列直到谓词首次返回 false 的元素)的 view
(类模板) (范围适配器对象)
由对适配视图的对应元素应用转换函数的结果组成的 view
(类模板) (定制点对象)
由对适配视图的相邻元素应用转换函数的结果组成的 view
(类模板) (范围适配器对象)