![](/img/trans.png)
[英]Why does the std::unique_ptr constructor accept an external pointer?
[英]Why not to accept std::unique_ptr by rvalue reference?
有人可以解釋為什么每個人都按值而不是右值引用傳遞std::unique_ptr
嗎?
根據我的觀察,這需要調用一個額外的移動構造函數。
這是一個 class 持有“指針”的例子。 它需要 3 次 move-ctor 調用才能按值獲取它,而需要 2 次調用才能通過引用獲取它:
#include <memory>
#include <iostream>
class pointer {
public:
pointer()
{ std::cerr << "ctor" << std::endl; }
pointer(const pointer&)
{ std::cerr << "copy-ctor" << std::endl; }
pointer& operator=(const pointer&)
{ std::cerr << "copy-assignment" << std::endl; return *this; }
pointer(pointer&&)
{ std::cerr << "move-ctor" << std::endl; }
pointer& operator=(pointer&&)
{ std::cerr << "move-assignment" << std::endl; return *this; }
~pointer()
{ std::cerr << "dtor" << std::endl; }
};
class A {
public:
// V1
A(pointer _ptr) : ptr(std::move(_ptr)) {}
// V2
A(pointer&& _ptr) : ptr(std::move(_ptr)) {}
private:
pointer ptr;
};
int main() {
// Three calls to move-ctor versus two calls if pass by rvalue reference
auto ptr = pointer();
A a(std::move(ptr));
// Two calls to move-ctor always
A a(pointer{});
}
通過引用、右值或其他方式傳遞unique_ptr
不會實際移動任何東西,因此僅查看 function 聲明您無法知道是否會發生移動。
另一方面,按值傳遞unique_ptr
保證傳入的指針將從中移出,因此甚至不必查看文檔,您就知道調用 function 可以使您擺脫指針的所有權。
int
而不是const int&
。 std::unique_ptr
只是單個指針值的 RAII 包裝器,因此移動它只是復制單個寄存器寬度值,然后將源清零。 這太微不足道了,避免移動沒有真正的好處。 畢竟,傳遞引用(未內聯時)的成本也是傳遞指針的成本,因此通過引用傳遞可能效率較低(因為如果未內聯,它必須遵循對真實 memory 的引用,然后拉從那里取出值;堆棧的頂部可能在 L1 緩存中,誰知道它存儲的位置是不是?)。
在實踐中,其中大部分將在啟用優化的情況下進行內聯,並且兩種方法都會得到相同的結果。 當按引用傳遞沒有任何好處時,按值傳遞是一個很好的默認設置,那么為什么不這樣做呢?
為什么每個人都按值而不是右值引用傳遞 std::unique_ptr?
它可能更常見,但不是“每個人”。
std::unique_ptr&&
參數的缺點是它沒有明確地與調用者溝通指針是否會被移動。 它可能總是移動,或者可能取決於某些條件。 您必須知道實現或至少 API 文檔才能確定。 std::unique_ptr
參數的相應好處是它單獨告訴聲明的讀者 function 將獲得指針的所有權。 出於這個原因,使用std::unique_ptr
參數可能是一個不錯的選擇,這可能是它更常見的部分原因。
std::unique_ptr&&
的好處是避免了額外的移動。 然而,移動std::unique_ptr
是一個非常快速的操作。 例如,與 memory 分配本身相比,它是微不足道的。 在大多數情況下,這根本無關緊要。
兩者之間的區別相當微妙。 std::unique_ptr&&
參數可能會在您測量到移動成本很高的情況下被考慮。 這不是很常見。 或者在您的 API 可能用於成本可能很高的情況下。 很難證明如果您正在編寫一個 public API 就不會發生這種情況,因此更有可能使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.