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
是引用o
的非 const xvalue (即,赋值是自移动赋值), - 如果
u
是一个 glvalue- 如果它是一个非 const xvalue,则它引用的对象处于有效但不确定的状态;
- 否则,它引用的对象不会被修改;
-
Assignable<T, U>
和 std::is_lvalue_reference<T>::value 之间不需要有任何蕴含关系。
[编辑] 等式保持
如果一个表达式在给定相等输入时产生相等输出,则该表达式是等式保持的。
- 表达式的输入由其操作数组成。
- 表达式的输出由其结果和表达式修改的所有操作数(如果有)组成。
每个要求为等式保持的表达式还必须是稳定的:在没有显式介入修改这些输入对象的情况下,对具有相同输入对象的此类表达式的两次求值必须具有相等的输出。
除非另有说明,否则requires-表达式中使用的每个表达式都必须是等式保持和稳定的,并且表达式的求值可能只会修改其非常量操作数。常量操作数不得修改。
[编辑] 注解
形式为 { expression } -> Same<T>&& 的推导约束有效地要求 decltype((expression))&& 与 T&&
的类型完全相同。这约束了表达式的类型及其值类别。
赋值不需要是全函数。 特别是,如果赋值给某个对象 x
会导致修改某个其他对象 y
,则 x = y 可能不在 =
的域中。 如果右操作数由左操作数直接或间接拥有(例如,使用指向基于节点的数据结构中的节点的智能指针,或使用类似 std::vector<std::any> 的东西),则通常会发生这种情况。