私はthis answerを読んでいたと著者は述べていboost best practicesを参照:C++でshared_ptrをC++ 11(std :: shared_ptr)に割り当てる:shared_ptrを一時変数に初期化するのはまだ悪いですか?
避け無名のshared_ptrを入力して保存するために一時使用します。 が、これは危険である理由は、この例を考えてみます。
void f(shared_ptr<int>, int);
int g();
void ok() {
shared_ptr<int> p(new int(2));
f(p, g());
}
void bad() {
f(shared_ptr<int>(new int(2)), g());
}
悪いが、メモリリークの可能性を認め、所定の位置に一時的 のshared_ptrを構築する一方で、機能OK]をクリックして、手紙にガイドラインを以下の。 関数の引数は不特定の順序で評価されるので、新しいint(2)を最初に評価する場合は 、g()の場合は可能で、例外がスローされた場合は をshared_ptrコンストラクタに渡すことはできません。 <...>
上記の例外安全性の問題も ブースト/ make_shared.hppで定義さmake_shared又はallocate_sharedファクトリ関数を用い によって除去することができます。これらのファクトリ関数は、割り当てを統合することによって の効率的なメリットも提供します。
私はアドバイスのこのビットはまだC++ 11 shared_ptr
に適用される場合、私はmake_shared
を使用して起動しますが、私は思っていたと思います。 g()
を投げてコールされるのを防ぐことができない理由を完全に理解していないため、私は尋ねます。
私はより良い説明を求めることができませんでしたが、このようなものの「アンパックオーダー」は必ずしも同じではないと私は思っています。また、私はまだrvalue参照の適切な理解を得るチャンスを持っていない。 –
@StevenLu:値の参照はそれとは関係ありません。 'auto &&'を使って' g() 'の結果を捕捉し、関数を呼び出すときに正しく転送できるようにしました。それは操作の順序とは関係がありません。また、順序はおそらく同じであろう... *コンパイラ全体ではない。 –
ああ。参照してください、私はそれが "私がまだ理解していないこと"であることを知っていたので、私はさらに調査しませんでした。しかし、この(擬似)コードは、コンパイラがintを割り振った後に 'g()' **を構築するコードをどのように生成する可能性があり、最初の2つの行が反対の注文(その場合、物事はうまくいくでしょう)。 –