簡體   English   中英

如何使用move構造函數正確處理shared_ptr的映射?

[英]How to handle a map of shared_ptr with move constructor correctly?

考慮到我有一個容器std::map<int, std::shared_ptr<MyClass>>並且我想將其填充到外部函數中,並避免應對其內容。 所以我有

typedef Container std::map<int, std::shared_ptr<MyClass>>

Container&& f(){
    Container bar;
    auto foo = std::shared_ptr<MyClass>(new MyClass());
    bar.insert(std::make_pair(0,foo));
    std::cout<<bar.at(1)->print_smth<<'\n'; //This works
    return std::move(bar);
}

int main(){
    Container baz(f());
    std::cout<<bar.at(1)->print_smth<<'\n'; //This doesn't
    // Container baz has element 1, but shared_ptr is invalidated, because it has 0 references.

}

如果我使用常規的復制構造函數,那么一切都會按預期進行。

這是過於復雜。 為什么不這樣說:

int main()
{
    Container baz { { 0, std::make_shared<MyClass>() } };

    // ...
}

如果絕對必須使用helper函數,則必須返回一個對象,而不是懸空的引用。 像這樣:

Container f()
{
    return Container { { 0, std::make_shared<MyClass>() } };
}

很難讓行人比這更沉迷,但是有一個最終的,永遠不會在家里使用的版本:

Container f()
{
   Container bar;
   auto p = std::make_shared<MyClass>;

   bar[0] = p;                        // Method #1
   // ---- ALTERNATIVELY ---
   bar.insert(std::make_pair(0, p));  // Method #2
   // ---- ALTERNATIVELY ---
   bar.emplace(0, p);                 // Method #3

   return bar;
}

問題是您要從f()返回引用。 一個右值引用仍然是一個引用,就像您永遠不會從函數返回對本地的引用一樣,使用右值引用也無法做到這一點。

好消息是您不必這樣做。 歸功於返回值的優化,您可以簡單地從f()返回一個Container ,它將完全按照您的期望進行操作。

暫無
暫無

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

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