Namespaces
Variants

std::experimental::ranges:: Assignable

From cppreference.net
template < class T, class U >

concept bool Assignable =
std:: is_lvalue_reference < T > :: value &&
CommonReference <
const std:: remove_reference_t < T > & ,
const std:: remove_reference_t < U > & > &&
requires ( T t, U && u ) {
{ t = std:: forward < U > ( u ) } - > Same < T > && ;

} ;
(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 右值引用(即该赋值是自移动赋值);
    • u 是泛左值:
      • 若其为非 const 右值引用,则其所指对象处于有效但未指定的状态;
      • 否则,其所指对象未被修改;

Assignable<T, U> std:: is_lvalue_reference < T > :: value 之间无需存在任何包含关系。

等值保持性

表达式若在输入相等时产生相等的输出,则称其具有 等值保持性

  • 表达式的输入由其操作数构成。
  • 表达式的输出由其结果及所有被该表达式修改的操作数(如有)构成。

每个要求保持相等性的表达式还必须满足 稳定性 要求:对此类表达式的两次求值,在输入对象相同且未进行任何显式修改的情况下,必须产生相等的输出结果。

除非另有说明,在 要求表达式 中使用的每个表达式都必须保持相等性且稳定,且该表达式的求值只能修改其非常量操作数。常量操作数不得被修改。

注释

形式为 { expression } - > Same < T > && 的推导约束实际上要求 decltype ( ( expression ) ) && 必须与 T&& 完全相同的类型。这同时约束了表达式的类型及其值类别。

赋值操作不必是全域函数。特别地,如果对某个对象 x 的赋值可能导致其他对象 y 被修改,那么 x = y 很可能不在 = 的定义域内。这种情况通常发生在右操作数被左操作数直接或间接拥有时(例如,使用基于节点的数据结构中的智能指针,或类似 std:: vector < std:: any > 的情形)。