3

例:

Foo make_foo(int a1, int a2){
  Foo f(a1,a2);
  return f;
}

そのような機能を何度か見たことがありますが、それは単にコーディングスタイル/好みの問題ですか、それとも目に見える以上のものがありますか?具体的には、この回答は、実装とそれが例外安全であるという主張について考えさせられましたmake_unique-それは作成とリターンの分割に関連していますか?それとも私はこれを読みすぎていますか?単純に書いてみませんか

Foo make_foo(int a1, int a2){
  return Foo(a1,a2);
}
4

5 に答える 5

7

作成と返却を組み合わせてもまったく問題ありません。教科書では、コードをある程度明確にするために、別々の行でそれを行うことがよくあります。

于 2011-06-01T04:07:15.400 に答える
4

それはあなたの要件に完全に依存していて、あなたはそれらを単一のステートメントに入れることができます。それはコードをより読みやすくするために行われます。

ほとんどの本やその他の技術リソースには、前の章で作成、インスタンス化、および返却のための個別のステートメントがありますが、読み続けると、それらは1つのステートメントにマージされます。

于 2011-06-01T04:06:26.050 に答える
4

あなたが参照する答えは実際には何か違うことに注意してください:

std::unique_ptr<T> ret (new T(std::forward<Args>(args)...));

このコード行では、明示的な動的割り当てが実行されます。ベストプラクティスでは、明示的な動的割り当てを実行するときはいつでも、結果を名前付きスマートポインターにすぐに割り当てる必要があります。詳細については、Boostshared_ptrのベストプラクティスのドキュメントまたはHerbSutterのGotWの記事「例外安全な関数呼び出し」を参照してください。

式をより大きな式の部分式として持つことは必ずしも危険ではありませんnewが、それは忘れがちなルールなので、常にベストプラクティスのガイドラインに従い、動的に割り当てられた新しいオブジェクトを名前付きスマートポインターに割り当てることをお勧めします。 。


とはいえ、名前付きオブジェクトを作成して返すというパターンには、少なくとも1つの利点があります。コードをすばやくステップ実行するときに、デバッガーでオブジェクトを「監視」する方が少し簡単です。

考えられる欠点の1つは、コンパイラが名前付きオブジェクトを使用して戻り値の最適化(RVO)を実行することがより困難になる可能性があることです。名前付き戻り値の最適化(NRVO)は、名前なしの一時的なRVOほど単純ではありません。最近のコンパイラにはどちらの方法でも問題がないと推測するのは危険ですが、私はC++コンパイラの最適化の専門家ではありません。

于 2011-06-01T04:10:58.950 に答える
0

個人的には、クラステンプレートを作成するときはいつでも、対応するmake_関数テンプレートを作成して、テンプレート引数を明示的に指定せずに、クラステンプレートのタイプのオブジェクトを作成できるようにします。もちろん、これは通常、C ++ 0xのautoセマンティクスを備えたコンパイラを使用する場合、または関数の引数として一時的なものを渡す場合のみですが、私の意見では、これらは両方とも、努力を正当化するのに十分な一般的なシナリオです。

そうは言っても、私は非テンプレート型を作成するためにこのようなコードを書いたことがありません。

于 2011-06-01T04:47:13.383 に答える
0

歴史的に、最初のバージョン

Foo make_foo(int a1, int a2)
{
    Foo f(a1,a2);
    return f; 
} 

一部のコンパイラ(古いMSVCなど)でNRVO最適化をトリガーする可能性が高くなりました。

バージョン2は、 RVOを実装するコンパイラーでも同様に機能するはずですが、歴史的にはそれほど信頼性がありませんでした。

于 2011-06-01T07:09:48.990 に答える