[英]std::Assignable concept
來自cppreference.com :
概念
Assignable<LHS, RHS>
指定所指定的類型和值類別的表達式RHS
可以被分配到一個左值表達式,其類型由指定的LHS
。給定
lhs
,一個引用對象lcopy
的左值 ,使得
decltype((lhs))
是LHS
,
rhs
,這樣的表達式,例如decltype((rhs))
是RHS
,
rcopy
,一個與rhs
相等的獨特對象,僅在以下情況下滿足
Assignable<LHS, RHS>
std::addressof(lhs = rhs) == std::addressof(lcopy)
(即賦值表達式產生一個引用左操作數的左值 );經過評估
lhs = rhs
:
lhs
是等於rcopy
,除非rhs
是指一個非const x值lcopy
(即,分配是自舉動賦值),如果
rhs
是glvalue :
如果它是非常量xvalue ,則它所引用的對象處於有效但未指定的狀態;
否則,它所引用的對象不會被修改;
我注意到了自我轉讓的便條。
如果rhs
指向lcopy
,則意味着lhs
甚至在分配之前就等於rcopy
(因為rhs
和rcopy
在先決條件下相等,並且lhs
和rhs
也相等,因為它們都指向同一對象),因此它應該等於rcopy
在那之后,由於未進行任何分配,因此, 除非注釋完全是多余的,對嗎?
僅當左操作數是左值,右操作數是右值並且都指向同一個對象時,才會出現自移動分配條件。 所以代碼本質上在做
x = std::move(x);
可能通過其他中間引用或獲取左值表達式的方式。
“除非”子句說的是,當分配是這種自我分配時,類型根本不需要滿足任何要求。 特別是,自移動分配可能會修改所涉及的單個對象,甚至表現出不確定的行為。
沒關系,因為這種可能性是在std::move
或其他xvalue的普通用法中無論如何都不會出現的。 預期使用xvalue表達式意味着不再需要該對象的舊值。 由於左側表達式指向同一對象,這意味着我們也不關心它發生了什么。
在兩側使用相同變量的實際代碼,例如x = std::move(x);
完全沒有意義。 通常,除非有充分的理由知道x值不會傳遞給函數,除非有充分的理由知道在給該對象一個新的特定值之前,該對象將無法通過其他方式(至少不是以對象狀態重要的方式)進行訪問。狀態(如果有的話),例如,已知不存在對該對象的其他引用,指針,迭代器等,或者以前無法使用的代碼將以涉及訪問該對象的方式再次使用。 對於標准庫,通常對xvalues的保證是[res.on.arguments] /1.3的原因:在調用庫函數時,“如果函數參數綁定到rvalue引用參數,則實現可以假定此參數是對此參數的唯一引用。”
值得一提的是,某些類提供了關於移出對象狀態的更具體的保證,而不僅僅是一般的“未指定但有效”的狀態。 一個類可以保證在移動構造函數或移動賦值之后,移出的對象始終為空。 但是請注意,如果允許x = std::move(x)
,則不能保證左側現在具有右側以前擁有的值,也不能保證右側已經擁有現在是空的!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.