[英]How were move semantics addressed before C++11?
我最近一直在閱讀移動語義,以及它是如何被引入C ++ 11的。 主要的要點是,通過“竊取”指向臨時對象的指針來創建對象,程序可以變得更有效率。 這比執行臨時對象的深層復制以創建新對象更有效。
在C ++ 11(及以后)中,這是通過使用rvalue引用來實現的。 所有臨時對象(程序內存中沒有已知位置的對象)都被視為右值。 具體來說,類構造函數現在可以重載以接受rvalue引用。
所以我很好奇,在C ++ 11之前,這個“昂貴的臨時對象復制”問題是如何解決的?
這樣做的主要方式是通過std::swap
。 std::swap
可以重載/專用於類型,它可以比默認的“通過臨時變量交換”更有效地執行,而不是執行淺交換。
通常,數據類型將提供swap()
成員函數,該函數可由此重載用於訪問數據類型的私有內部。 (例如;參見std :: vector :: swap )
例如; 要將元素“移動”到vector
,可以使用以下代碼:
class MyListOfVectors {
private:
//using `std::vector<int>` as an example of a "movable" type.
std::vector<std::vector<int>> list;
public:
void emplace_back(std::vector<int> &n) {
using std::swap;
list.push_back(std::vector<int>());
swap(list.back(), n);
//(possibly add something to rollback the `push`
// in case swap fails; to provide the strong
// exception guarantee)
}
};
要通過“move”返回元素,可以使用以下代碼:
std::vector<int> MyListOfVectors::pop_back() {
using std::swap;
std::vector<int> r;
swap(list.back(), r);
list.pop_back();
return r; //Trust in copy elision to avoid any actual copies.
}
我沒有這方面的參考,但我相信允許/鼓勵標准算法為此目的使用std::swap
。
另外,如果你覺得你想用C ++ 11方式做事,你也可以使用boost :: move ,它提供了C ++ 03中C ++ 11移動語義的模擬(雖然它在技術上違反了嚴格別名,因此有未定義的行為)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.