[英]The move function in unique_ptr C++03 emulation
我試圖理解如何實現unique_ptr的C ++ 03仿真 。 unique_ptr非常像std :: auto_ptr但更安全。 在auto_ptr隱式轉移所有權(即靜默)的情況下,它會吐出編譯器錯誤。 例如,一個簡單的任務。 函數move
是模擬unique_ptr安全性的關鍵。
問題:
接受引用並將其轉換為右值的第三個移動函數實現(簡化)如下。
T move(T &t) { return T(detail_unique_ptr::rv<T>(t)); }
在上面的代碼中,顯式轉換為T似乎是不必要的。 實際上,Visual Studio 2010非常高興,沒有明確轉換為T.
T move(T &t) {
return detail_unique_ptr::rv<T>(t);
}
然而,g ++,clang,Comeau不喜歡第二個版本。 這些編譯器抱怨unique_ptr<T>
沒有構造函數將detail_unique_ptr::rv<T>
作為參數。 這是為什么? unique_ptr已經定義了一個(非顯式)構造函數,它將detail_unique_ptr::rv<T>
作為參數。 為什么不自動拾取?
原因是因為你無法在不進行用戶定義轉換的情況下使用另一個unique_ptr初始化unique_ptr(通過將rvalue傳遞給unique_ptr的rv-taking構造函數來轉換為rv)。 但是當沒有顯式調用unique_ptr
的ctor時(如在unique_ptr(...)
),你做了一個復制初始化,在你的情況下首先成功構造一個rvalue臨時unique_ptr,但是然后無法將那個臨時復制到返回值目標對象中,因為在該副本中,不允許用戶定義的轉換(這也稱為原則規則“初始化中沒有兩個用戶定義的轉換”)。 Msvc允許副本使用ctor采用nonconst unique_ptr引用,這是非標准的。
從同一個類的對象進行類的初始化復制時,沒有這樣的兩步初始化。 源對象只是傳遞給unique_ptr
的非顯式構造函數,它將使用rv-taking構造函數將其轉換為rv
,並通過這種方式成功構造返回值目標對象。
出於同樣的原因,沒有從unique_ptr<Derived>
到unique_ptr<Base>
隱式轉換。 在第一步中,將成功創建unique_ptr<Base>
,但是當將該臨時值復制到unique_ptr<Base>
目標對象時,可以使用沒有用戶定義的轉換的限制會阻止成功。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.