![](/img/trans.png)
[英]std::move_if_noexcept calls copy-assignment even though move-assignment is noexcept; why?
[英]Rationale for std::move_if_noexcept still moving throwing move-only types?
noexcept
或者沒有復制構造函數(僅移動類型) 我發現這個相當令人驚訝,因為只有移動類型的投擲移動器仍然會使用move_if_noexcept
的代碼調用此移動move_if_noexcept
。
有沒有給出一個徹底的理由呢? (可能直接或在N2983之間?)
不編碼會不會更好,而不是仍然不得不面對不可恢復的移動場景? N2983中給出的vector
示例很好:
void reserve(size_type n)
{
... ...
new ((void*)(new_begin + i)) value_type( std::move_if_noexcept( (*this)[i]) ) );
}
catch(...)
{
while (i > 0) // clean up new elements
(new_begin + --i)->~value_type();
this->deallocate( new_begin ); // release storage
throw;
}
*!* // -------- irreversible mutation starts here -----------
this->deallocate( this->begin_ );
this->begin_ = new_begin;
... ...
標記線中給出的注釋實際上是錯誤的 - 對於可以投擲移動構造的僅移動類型,當我們將舊元素移動到新位置時,實際上已經開始 - 可能失敗 - 不可逆轉的突變。
簡要地看一下,我會說投擲移動的類型不能放入矢量中,否則它可能不應該?
簡要地看一下,我會說投擲移動的類型不能放入矢量中,否則它可能不應該?
我相信你已經很好地總結了委員會對於僅移動 - 禁止(假) - 類型的容器的選擇。
答:委員會絕對認為他們無法默默地將現有的C ++ 03代碼從具有強大的異常安全性轉變為具有基本的異常安全性。
B.對於具有強大異常安全性的那些函數,委員會更傾向於使這些成員繼續具有強大的異常安全性,即使對於尚不可能編寫的代碼(例如,用於操作僅移動類型的函數)。
委員會意識到它可以完成上述兩個目標,但B)中的情況除外,其中只有移動類型可能在移動施工期間拋出。 這些情況僅限於vector
IIRC的幾個成員函數: push_back
, reserve
。 注意, vector
其他成員已經只提供了基本的異常安全性(即使在C ++ 98/03中),例如:賦值,插入(除非在末尾插入),擦除。
考慮到所有這些,委員會的決定應該是客戶創建一個只移動 - 無法(錯誤)類型的vector
,對於客戶來說,將基本的強大異常安全性放松是更有用的(因為它已經是為了其他向量成員),而不是拒絕編譯。
這只是客戶端為C ++ 11編寫的新代碼,而不是遺留代碼,因為在C ++ 11之前不存在僅移動類型。 毫無疑問,C ++ 11的教育工作者應該鼓勵他們的學生編寫noexcept(真正的)移動成員。 但是,具有基本異常安全保證的代碼不是那么危險,也不是不尋常的,因此應該禁止它。 畢竟,std :: lib已經充滿了只帶有基本異常安全保證的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.