4

私がコンテナを持っていて、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.

}

従来のコピーコンストラクターを使用すると、すべてが期待どおりに機能します。

4

2 に答える 2

6

これは非常に複雑です。なぜこれを言ってはいけません:

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

    // ...
}

どうしてもヘルパー関数を使用する必要がある場合は、ぶら下がっている参照ではなく、オブジェクトを返す必要があります。このようなもの:

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

これ以上の歩行者を満足させるのは難しいですが、最後の、家庭で使用されることのないバージョンが1つあります。

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;
}
于 2012-08-28T15:27:22.217 に答える
0

問題は、から参照を返していることですf()。右辺値参照は引き続き参照であり、関数からローカルへの参照を返すことは決してないのと同じように、右辺値参照でもそれを行うことはできません。

良いニュースは、そうする必要がないということです。戻り値の最適化のおかげで、Containerからを返すだけで、f()探しているものを正確に実行できます。

于 2012-08-28T15:43:11.250 に答える