std::experimental::ranges::Assignable
template< class T, class U > concept bool Assignable = |
(范围 TS) | |
概念 Assignable<T, U>
指定了类型和值类别由 U
指定的表达式可以赋值给类型由 T
指定的左值表达式。
给定
-
t
,类型为 std::remove_reference_t<T> 的左值,引用对象o
, -
u
,表达式,使得 decltype((u)) 为U
, -
u2
,与u
相等的独立对象,
Assignable<T, U>
仅在满足以下条件时才成立:
- std::addressof(t = u) == std::addressof(o)(即,赋值表达式产生一个引用左侧操作数的左值);
- 在评估 t = u 之后
-
t
等于u2
,除非u
是一个非 const xvalue,引用o
(即,赋值是一个自身移动赋值), - 如果
u
是一个 glvalue- 如果它是非 const xvalue,它引用的对象处于有效但未指定的狀態;
- 否则,它引用的对象不会被修改;
-
Assignable<T, U>
与 std::is_lvalue_reference<T>::value 之间可能不存在任何包含关系。
[编辑] 等效保留
如果表达式在给定相等输入的情况下产生相等的输出,则该表达式是等效保留的。
- 表达式的输入包括其操作数。
- 表达式的输出包括其结果和表达式修改的所有操作数(如果有)。
每个要求等效保留的表达式都进一步要求是稳定的:对具有相同输入对象的表达式进行两次评估必须具有相等的输出,前提是这些输入对象没有进行任何明确的中间修改。
除非另有说明,否则requires-expression 中使用的每个表达式都要求等效保留和稳定,并且表达式的评估只能修改其非 const 操作数。常量操作数不得修改。
[编辑] 注释
形式为 { expression } -> Same<T>&& 的推导约束实际上要求 decltype((expression))&& 与 T&&
具有完全相同的类型。这既约束了表达式的类型,也约束了其值类别。
赋值不一定是全函数。特别是,如果将某个对象 x
赋值可能会导致另一个对象 y
被修改,那么 x = y 可能不在 =
的域中。这通常发生在右操作数直接或间接地由左操作数拥有时(例如,使用指向节点型数据结构中节点的智能指针,或使用类似 std::vector<std::any> 的东西)。