簡體   English   中英

來自抽象類的unique_ptr的shared_ptr

[英]shared_ptr from unique_ptr of abstract class

我試圖遵循Herb Sutter的C ++指南,在這種情況下更喜歡unique_ptr到原始指針和shared_ptr 支持std::unique_ptr一個參數是在某些時候需要轉換為shared_ptr

在我的例子中,我有一個unique_ptrvector ,我需要傳遞給一個帶有shared_ptr vector的方法。 我希望能寫出類似的東西:

for (auto &uniquePtr : vectorUnique)
    vectorShared.push_back(make_shared<Abstract>(move(uniquePtr));

這為我為基於Xcode 7.1C++11工具鏈配置了以下錯誤:

錯誤:字段類型'Abstract'是一個抽象類。

當我使用make_shared時,似乎STL試圖保持Abstract類型的具體實例。 這似乎使Sutter先生的建議在許多情況下變得不可行,所以我確信我一定做錯了! 我求助於寫作:

for (auto &uniquePtr : vectorUnique) {
    auto ptr = uniquePtr.get();
    auto shared = shared_ptr<Abstract>(ptr);
    vectorShared.push_back(shared);
    uniquePtr.release();
}

有一個更好的方法嗎?

make_shared使用給定的參數構造一個新對象,並向其返回一個shared_ptr 所以編譯器需要一個構造函數Abstract(std::unique_ptr<Abstract>) ,這可能不是你擁有的。

你想要的是shared_ptr的構造函數,它接受一個unique_ptr參數:

    vectorShared.push_back(shared_ptr<Abstract>(move(uniquePtr)));

而且,因為它不explicit ,那么

    vectorShared.emplace_back(move(uniquePtr));

只會工作(我在Richard Hodges的建議中使用了emplace_back來避免冗余復制)。 甚至還有一個標准算法,所以你不需要for循環:

    std::move(vectorUnique.begin(), vectorUnique.end(),
              std::back_inserter(vectorShared));

如果您經常需要這個,您可以定義一個函數:

#include <vector>
#include <memory>
#include <algorithm>

template<typename T>
std::vector<std::shared_ptr<T>>
        convert_to_shared(std::vector<std::unique_ptr<T>>&& vu)
{
    using std::begin;
    using std::end;
    std::vector<std::shared_ptr<T>> vs;
    vs.reserve(vu.size());
    std::move(begin(vu), end(vu), std::back_inserter(vs));
    return vs;
}


// Example of use
class Abstract {};
int main()
{
    std::vector<std::unique_ptr<Abstract>> vectorUnique;
    std::vector<std::shared_ptr<Abstract>> vectorShared
        = convert_to_shared(std::move(vectorUnique));
}

抱歉這個可怕的名字(我願意接受建議)。 如果省略對reserve()的調用,則可以將其推廣到更多容器。

我會這樣做:

for (auto &uniquePtr : vectorUnique) {
    vectorShared.emplace_back(std::move(uniquePtr));
}

暫無
暫無

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

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