[英]Does an exception use move semantics when thrown in C++11?
http://www.drdobbs.com/cpp/practical-c-error-handling-in-hybrid-env/197003350?pgno=4
在這篇文章中,Herb Sutter 解釋了拋出異常需要一個異常的副本,因為它是作為臨時創建的,因此使用std::auto_ptr
來繞過復制開銷。 鑒於 C++11 中提供了移動語義,這仍然是必要的嗎?
我剛剛檢查過,標准允許
由於這些遺漏是允許的,規范要求首先將復制或移動的來源視為右值。 因此,這意味着如果可能,將移動相應的對象。 當然,復制和移動省略仍然是首選。
我被告知,將 catch 子句參數的異常對象初始值設定項作為右值初始值設定項的考慮可能會從標准中刪除(因為通常情況下,不可能在所有情況下都檢測到在省略時程序的行為何時保持不變)復制/移動),所以我建議不要依賴這個(上面的第二個項目)。
您仍然可以依賴的是將局部變量移動到異常對象中,如throw x;
(上面的第一個項目符號)。
從異常對象移動現在不是強制性的。
這是 C++11 的缺陷。 參見CWG1493 。
但是現代 C++ 提供了更多功能:“使用移動語義和異常安全移動”
struct demo
{
demo() = default;
demo(const demo &) { cout << "Copying\n"; }
// Exception safe move constructor
demo(demo &&) noexcept { cout << "Moving\n"; }
private:
std::vector<int> m_v;
};
int main()
{
demo obj1;
if (noexcept(demo(std::declval<demo>()))){ // if moving safe
demo obj2(std::move(obj1)); // then move it
}
else{
demo obj2(obj1); // otherwise copy it
}
demo obj3(std::move_if_noexcept(obj1)); // Alternatively you can do this----------------
return 0;
}
noexcept(T(std::declval<T>()))
以檢查是否T
的移動構造函數存在且noexcept
,以決定是否我們要創建的實例T
通過移動的另一個實例T
(使用std::move
)。std::move_if_noexcept
,它使用noexcept
運算符並轉換為右值或左值。 此類檢查用於std::vector
和其他容器。std::move_if_noexcept
,它僅在移動構造函數是異常安全的情況下才移動關鍵數據的所有權。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.