私はこれについて私の同僚とこの議論をしました。そして、どちらがより最適な「可能性」があるかについて、より多くの人々の意見を知りたいですか? PS: コードが単なる hello world プログラムの場合、-O3 は同じコードになりますが、このコード セグメントが大規模なプロジェクトの途中にあるシナリオについて話しています。
2 に答える
コンテキストが決定的に重要です。そして、あなたのプロファイラーはおそらく、それを気にしないようにあなたに言うでしょう.
この場合、std::string
とにかく new を構築する必要があり、「有効期間が延長された一時値への const 参照」は、実際にはコンパイラにさらに多くの作業を引き起こすだけです (同等/同一のコードを出力するため)。
私は明確にすることを選びます:
メソッドではなくコードの意図
そう
std::string tmp("Hello");
または
std::string tmp = "Hello";
意図を十分に表現します。
コンパイラが同じコードを生成する可能性がありますが、参照を使用すると、カジュアルな読者には誤解を招く可能性があります。リテラルで初期化する代わりに、関数の戻り値を使用したことを考慮してください。
std::string f();
std::string const & r = f(); // [1]
[1]のタグが付けられた行は、別の場所で管理されているオブジェクトへの参照(低コストの操作)を作成しているようです。コードの読者は、参照された文字列が外部で変更される可能性があるかどうか、またはぶら下がっている参照を残して破壊される可能性があるかどうかを把握しようとします。彼らはのドキュメントに行き、f()
それが実際には一時的なものであることを確認し、次に元のコードに戻って、これがスマートなトリックをプレイしているプログラマーにすぎないことを理解する必要があります。
一方std::string s = f();
、意図ははるかに明確です。f()
表現するものが何であれ、そのコピーはローカルコンテキストで維持されます。オブジェクトは外部から変更されることはなく、存続期間はまさにそれが定義されているスコープです。
どちらの場合も動作は実際には同じですが、一方の場合はカジュアルな読者には明らかであり、もう一方の場合は読者がそれを理解する必要があることに注意してください。私は可能な限りすべての場合にローカルオブジェクトを使用し、ライフタイムの延長を値がそれをカットしないいくつかのケースに制限します(実際には一度だけ必要でした)。