簡體   English   中英

移動 unique_ptr 的內容

[英]moving the content of a unique_ptr

所以如果我有一個可移動的 (rval) std::unique_ptr,我可以使用簡單的賦值來移動內容而不是復制嗎? (指向object的內容,而不是指向它的指針)

看起來我做不到,但是“也許我做錯了”?

如果不是,不允許這樣做的理由是什么?

細節:

所以我已經成為 class 的所有者,其方法是從 Hell 返回 std::map,我真的不想在所有使用 /my/ class 的地方包含 hell.h,只是在少數幾個真正使用的地方想go那里。

所以我的想法是改變方法的返回簽名

#include "hell.h"
std::map<std::string, Hell> CopyTheObjectSpecified(...);

class Hell;
std::unique_ptr<std::map<std::string, Hell>> CopyTheObjectSpecified(...);

而且,對於 new 和 delete 的成本,我現在不需要詳細說明 Hell,除非調用該方法,並且該代碼將安全地由 unique_ptr 限定范圍。 鑒於 map 副本有很多分配,我不關心多一個。

(ben-v 建議我在 Hell 周圍建立一個編譯防火牆 - 看它的好方法)

但是,其中一位來電者正在做:

void Angel(std::map<std::string, Hell>& hell)
{
  hell = CopyTheObjectSpecified(...);
}

用於減少移動分配(甚至是完整的返回復制省略 - 可能不是)

所以現在我正在做一個

void Angel(std::map<std::string, Hell>& hell)
{
  hell = * CopyTheObjectSpecified(...);
}

或者更冗長,視覺上令人反感,但幾乎可以在任何地方跟蹤和注射:

void Angel(std::map<std::string, Hell>& hell)
{
  hell = CopyTheObjectSpecified(...) .get()[0] ;
}

在我看來,查看調試, *get()的重載似乎沒有看出 unique_ptr 是一個 r-val,因此內容也應該作為 r-val 返回。

(請注意,我在這里的意圖是 rval unique_ptr 實例繼續擁有它指向的 object,並且當它正常離開 scope 時將刪除它,但是 object 將通過移動剝離其內容。)

所以這是調用復制/刪除語義而不是移動語義,這是一種開銷。 我不能讓代碼運行得更慢!

當然,我可以簡單地添加一個 std::move(),但是當原作者取回它時,那將是一種額外的味道。 我仍然看到“未封裝”的 std::move 作為氣味。 也許最終我會習慣看到它。

void Angel(std::map<std::string, Hell>& hell)
{
  hell = std::move( * CopyTheObjectSpecified(...) ) ;
}

或者使用交換操作(感謝 Ben Voigt)

void Angel(std::map<std::string, Hell>& hell)
{
  hell.swap ( * CopyTheObjectSpecified(...) ) ;
}

(是的,CopyTheObjectSpecified() 的最佳(目前)實現是實際制作並返回一個副本,而不是返回一些對不斷變化的數據的 shared_ptr const 引用)

或者我可以將可移動性最低限度地封裝在 unique_ptr 的包裝器 class 中。 使用 when-rval-content-movable unique_ptr 有危險嗎?

目前我們編碼為 c++11。也許我需要后期標准的幫助才能正確執行此操作? 但這可能會幫助我制定一個可讀和可轉移的解決方案。

呃。 我只想要 /my/ 類的 /out/ 這個方法! 但今天這不是一個選擇。

在最簡單的層面上,似乎不需要 unique_ptr,因為std::map可以在不完整的類型上實例化就好了。 所以你可以這樣做:

class Hell;
std::map<std::string, Hell> CopyTheObjectSpecified(...);

並且您只需要 #include 代碼即可將某些內容放入 map 或將其從 map 中取出(或復制/復制整個地圖)。 std::map已經包含一個間接級別,這意味着它可以在不知道鍵/值類型的細節的情況下移動。

所以

void Angel(std::map<std::string, Hell>& hell)
{
  hell = CopyTheObjectSpecified(...);
}

應該繼續工作就好了。

我不確定我的回答是否有幫助,但據我所知,創建unique_ptr意味着 object 的所有權無法更改,這意味着它僅在已定義的 scope 中有效/創建所以我認為你不能移動它的內容,因為它會改變所有權。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM