3

を返すメソッドがあると仮定しますstd::set:

std::set<string> MyClass::myMethod() const
{
   std::set<string> result;
   // ... some code to fill result ...
   return result;
}

呼び出し側ではmyMethod、次の 2 つの方法で結果を保存できます。

void MyClass::test()
{
const std::set<string>  s1 = myMethod();  // 1
const std::set<string>& s2 = myMethod();  // 2 (using reference)
// ... some code to use s1 or s2 ...
}

私の質問は次のとおりです。

  • それらの間に違いはありますか?
  • どちらの方法がより効果的で効果的ですか?
4

5 に答える 5

4
const std::set<string>  s1 = myMethod();  // 1

の戻り値がmyMethods1 にコピーされます。サイズによっては、これには長い時間がかかる場合があります。

const std::set<string>& s2 = myMethod();  // 2 (using reference)

によって返される一時への参照myMethodが格納されます。これにより、上記の方法よりもコピーが 1 つ少なくなるため、少し高速になります (最適化がない場合)。

これは、その時点で存在しなくなる変数への参照を作成するために使用される特殊なケースの機能;です。これはconst&、あなたの例では Rvalue 参照である場合にのみ機能します- &&(@Kosに感謝します)。

于 2012-12-17T09:27:20.023 に答える
3

理論的には、余分なコピーを必要としないため、2 番目のバージョンの方が優れています。

実際には、RVO が作動する可能性が高いため、ほぼ同じになるはずです。

于 2012-12-17T09:26:36.233 に答える
2

実用上の違いはほとんどありません。私は以下をテストしましたg++ 4.7.2

#include <string>

extern std::string f();
extern void g(const std::string&, const std::string&);

int main() {
  std::string        x = f();
  const std::string& y = f();
  g(x, y);
}

そして、両方の呼び出しに対して同じコードを生成しますf():

LEHB0:
        call    __Z1fv
LEHE0:
        leaq    16(%rsp), %rdi
LEHB1:
        call    __Z1fv
LEHE1:
        leaq    16(%rsp), %rsi
于 2012-12-17T09:35:02.143 に答える
2

はい、これらは異なります。

  1. const std::set<string> s1 = myMethod(); // 1: 一時オブジェクトをコピーします

  2. const std::set<string>& s2 = myMethod(); // 2 (using reference): 一時ファイルの有効期間が長くなり、1 つのコピーが回避されます

今週の達人 #88 を参照してください。コンパイラは、効率的に同じにすることでこれを最適化できることに注意してください。

于 2012-12-17T09:27:29.820 に答える
1
  1. 最初のバージョンでstd::setオブジェクトが作成され、この行に移動されます

    const std::set<string> s1 = myMethod();

  2. std::setこれにより、メソッドで作成されたオブジェクトの有効期間が延長されます。

    const std::set<string>& s2 = myMethod();

したがって、パフォーマンスに関しては、どちらも同じことを行っています。

于 2012-12-17T09:27:48.993 に答える