std::experimental::ranges::Assignable
template< class T, class U > concept bool Assignable = |
(ranges 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 中使用的每个表达式都必须保持相等且稳定,并且表达式的评估只能修改其非常量操作数。常量操作数不得修改。
[编辑] 注意
形式为 { expression } -> Same<T>&& 的推导约束实际上要求 decltype((expression))&& 与 T&&
是完全相同的类型。这约束了表达式的类型及其值类别。
赋值不一定是全函数。特别是,如果将某个对象 x
赋值可能导致另一个对象 y
被修改,那么 x = y 很可能不在 =
的定义域内。这通常发生在右操作数直接或间接由左操作数拥有时(例如,带节点数据结构中节点的智能指针,或者像 std::vector<std::any> 这样的情况)。