2012-12-28 111 views
8

this參考,它允許const右值作爲移動構造函數移動構造函數簽名

Type::Type(const Type&& other); 

可移動物體怎麼能const?即使這在技術上是允許的,是否有這種聲明會有用的情況?

+4

簡單的回答:不,沒有,因爲它打破了移動語義學的整個目的。還要注意'&&'不一定要說「可移動」。它只是說「右值參考」。並且* MoveConstructible *在沒有移動的情況下會複製,所以你可以說'T const &&'move ctor可能只是複製,但是呃。 – Xeo

+0

好吧,'Type'可以聲明一個'mutable'變量,'mutable'變量*可以''const'移動構造函數修改。因此,一個'const'移動構造函數可以做一個對象的淺拷貝(而一個拷貝構造函數可以做一個深層拷貝),並且在被移動的地方設置一個叫做'dead'的可變布爾標誌或者類似的''true'目的。然後'Type'(最重要的是析構函數)的函數將檢查該標誌。這是無稽之談嗎? –

回答

9

可移動物體如何成爲const

它不能,但那不是語言所說的。該語言表示具有該簽名的構造函數是一個「移動構造函數」,但這並不意味着該參數被移出,而只是意味着構造函數符合「移動構造函數」的要求。移動構造函數不需要移動任何東西,如果參數是const它不能。

有沒有這種情況下這種聲明是有用的?

是的,但不是很經常。如果要防止在const臨時變量作爲參數傳遞時通過重載解析來選擇另一個構造函數,這會很有用。

struct Type 
{ 
    template<typename T> 
    Type(T&&); // accepts anything 

    Type(const Type&) = default;  
    Type(Type&&) = default; 
}; 

typedef const Type CType; 

CType func(); 

Type t(func()); // calls Type(T&&) 

在此代碼func()臨時返回將不完全匹配的複製或移動建設者的參數,所以會調用接受任何類型的模板構造。爲了防止這種情況,你可以提供不同的過載取一個const右值,並委託授權的拷貝構造函數:

Type(const Type&& t) : Type(t) { } 

或者,如果你想防止代碼編譯,將其定義爲刪除:

Type(const Type&& t) = delete; 

有關使用const rvalue引用的標準示例,請參閱https://stackoverflow.com/a/4940642/981959