2012-08-24 48 views
1

下面的代碼將拋出一個警告:爲什麼我不能用由函數返回的unique_ptr交換unique_ptr?

警告C4239:使用非標準擴展: '參數':從 '的std ::的unique_ptr < _Ty>' 到 '的std ::的unique_ptr < _Ty> &'

轉換
std::unique_ptr<T> foo() { return std::unique_ptr<T>(new T); } 
std::unique_ptr<T> myVar; 
myVar.swap(foo()); 

我想知道處理這種情況的正確方法是什麼。

回答

7

std::unique_ptrswap構件函數採用一個非const左值和參考表達foo()是一個rvalue作爲foo是返回一個對象(相對於基準)的功能。您不能將右值綁定到非常量左值引用。

注意,你可以做掉周圍的其他方式:

foo().swap(myVar); 

最簡單的方式做的是直初始化:

std::unique_ptr<T> myVar(foo()); 
+1

不幸的是,Visual Studio中不支持統一初始化語法 – Praetorian

+0

@禁衛軍:打擾了。讓我修復。 –

1

std::unique_ptr::swap採取非const參考其他指針。您不能將r值綁定到非const引用,儘管VC++允許通過非標準擴展。因此警告。

要擺脫此警告,請將foo的返回值存儲在變量中,然後交換或反轉交換順序。

foo().swap(myVar); 
1

您正在嘗試交換臨時文件。你可以代替試試這個:

std::unique_ptr<T> foo() { return std::unique_ptr<T>(new T); } 
std::unique_ptr<T> myVar1; 
std::unique_ptr<T> myVar2 = foo(); 
myVar1.swap(myVar2); 

注意這不是專門針對std::unique_ptr。下面是出於同樣的原因非法的:

void foo(std::string& s) { .... } 
std::string bar() { .... } 

foo(bar()); 
+0

交換臨時文件有什麼問題?這不是VS11中的警告 – aCuria

+1

@aCuria該語言不允許您將非常量引用綁定到臨時對象。邏輯是,改變即將消失的東西是沒有意義的。 – juanchopanza

+0

+1的答覆,但我認爲對我來說它是有道理的,它會立即消失(dtor被調用)。我將它用於圖形資源(比如紋理),這些圖形資源預計會是屏幕大小的。當屏幕分辨率發生變化時,舊紋理應換成新紋理,舊紋理被破壞......因此,我希望做texture.swap(newtexture); – aCuria

相關問題