15

以下は、ライブラリのコーディング スタイル ドキュメントから見つけた抜粋です。

可能であれば、名前付きオブジェクトを格納するよりも一時オブジェクトを使用する方がよい場合があります。たとえば、次のようになります。

DoSomething( XName("何とか") );

それよりも

XName n("何とか"); DoSomething( n );

これにより、コンパイラによる呼び出しの最適化が容易になり、関数のスタック サイズが縮小される可能性があります。ただし、一時的なオブジェクトの有効期間を考慮することを忘れないでください。

オブジェクトを変更する必要がなく、有効期間の問題も問題ないと仮定すると、このガイドラインは正しいでしょうか? このご時世だから仕方ないと思っていました。ただし、名前付きオブジェクトを回避できない場合もあります。

XName n("blah");
// Do other stuff to mutate n
DoSomething( n );

また、ムーブ セマンティクスを使用すると、一時変数が削除されるため、次のようなコードを記述できます。

std::string s1 = ...;
std::string s2 = ...;
std::string s3 = ...;
DoSomething( s1 + s2 + s3 );

ではなく (コンパイラは C++03 で次のように最適化できると聞きました):

std::string s1 = ...;
std::string s2 = ...;
std::string s3 = ...;
s1 += s2; 
s1 += s3;  // Instead of s1 + s2 + s3
DoSomething(s1);

(もちろん、上記は に要約される可能性がありますが、上記measure and see for yourselfの一般的なガイドラインに真実があるかどうか疑問に思っていました)

4

3 に答える 3

4

受け入れられた答えは間違っていると思います。一時オブジェクトに名前を付けることは避けほうがよいでしょう。

その理由は、

struct T { ... };
T foo(T obj) { return obj; }

// ...

T t;
foo(t);

その後t、コピー構築され、コピーコンストラクターに観察可能な副作用がある場合、これを最適化することはできません。

対照的に、 と言った場合、潜在的な副作用に関係なくfoo(T())、コピー コンストラクターの呼び出しを完全に回避できます。

したがって、一般的には、一時オブジェクトに名前を付けることを避けることをお勧めします。

于 2013-07-04T20:38:12.917 に答える
3

ここにいくつかのポイントがあります:

  • どのコンパイラが最適化し、何を最適化しないかを正確に知ることはできません。最適化は複雑です。オプティマイザの作成者は、何かを壊さないように細心の注意を払う傾向があります。オプティマイザーが誤って何かを最適化すべきではないと判断するというバグに遭遇する可能性があります。コンパイラのコーディング標準は非常に高くなっています。それにもかかわらず、それらは人間によって書かれています。
  • この特定のコーディング スタイルの抜粋は、あまり合理的ではないように思えます。私たちの時代のコンパイラは、ほとんど常に優れています。オプティマイザーが何かを混乱させるとは考えにくいXName n("blah"); DoSomething(n);- このコードは単純すぎる.

同様のコーディングガイドラインを次のように配置します。

  • 理解しやすく変更しやすい方法でコードを記述します。
  • パフォーマンスの問題が確認されたら、生成されたコードを調べて、コンパイラを喜ばせる方法を考えてください。

反対の方法ではなく、この順序で問題に対処することをお勧めします。

于 2013-07-04T00:48:34.807 に答える