2015-06-24 110 views
20

我有一個定製刪除創建的unique_ptr並返回一個函數:移動與定製刪除一個的unique_ptr到一個shared_ptr

auto give_unique_ptr() { 
    auto deleter = [](int* pi) { 
     delete pi; 
    }; 
    int* i = new int{1234}; 
    return std::unique_ptr<int, decltype(deleter)>(i, deleter); 
} 

在該功能的客戶端代碼,我想移動unique_ptrshared_ptr,但我不知道該怎麼做,因爲我不知道我的自定義刪除器的decltype以外的函數。

我猜應該是這個樣子:

auto uniquePtr = give_unique_ptr(); 
auto sharedPtr = std::shared_ptr<..??..>(std::move(uniquePtr)); 

我有什麼寫的,而不是?? ..才能得到正確的類型?

如果可能,shared_ptr的行爲會很好,並在使用次數達到零時致電我在give_unique_ptr()函數內創建的自定義刪除程序?

+0

請記住'shared_ptr' *擦除刪除器。唯一的模板參數是當前視圖中指向的類型。 – o11c

+0

@ o11c這是什麼意思?我嘗試了@Nawaz提出的解決方案,並在'shared_ptr'被銷燬後調用deleter。 – j00hi

+0

這意味着刪除者的類型與'shared_ptr'類型無關。你甚至可以投射到'shared_ptr ',它仍然會調用原始的刪除器。 – o11c

回答

19

如果你知道(或要明確什麼類型)的對象類型,那麼你可以這樣做:

std::shared_ptr<int> sharedPtr(std::move(uniquePtr)); 

std::shared_ptr構造將採取deletor的照顧。


如果,但是,希望來推斷,那麼:

auto sharedPtr = make_shared_from(std::move(uniquePtr)); 

其中make_shared_from是:

template<typename T, typename D> 
std::shared_ptr<T> make_shared_from(std::unique_ptr<T,D> && p) 
{ 
    //D is deduced but it is of no use here! 
    //We need only `T` here, the rest will be taken 
    //care by the constructor of shared_ptr 
    return std::shared_ptr<T>(std::move(p)); 
}; 

希望有所幫助。

+2

IMO,make_shared_from'可能會更好一些,讓右邊的引用使它看起來好像是從 –

+3

@RyanHaining中移出來的,甚至是一個值,這在大多數情況下更像C++ 11-idiomatic。 – o11c

+0

@RyanHaining:那也不錯。 'move_from'而不是'make_shared_from'如何? – Nawaz

14
auto uniquePtr = give_unique_ptr(); 
auto sharedPtr = std::shared_ptr<decltype(uniquePtr)::element_type>(std::move(uniquePtr)); 

是的,shared_ptr將存儲 - 並在以後使用 - 自定義刪除器。

相關問題