constを参考に一時的なもので、コピー-C++
-
24-09-2019 - |
質問
をご検討ください以下のコード
struct foo
{
foo()
{
std::cout << "Constructing!" << std::endl;
}
foo(const foo& f)
{
std::cout << "Copy constructing!" << std::endl;
}
~foo()
{
std::cout << "Destructing.." << std::endl;
}
};
foo get()
{
foo f;
return f;
}
int main()
{
const foo& f = get();
std::cout << "before return" << std::endl;
return 0;
}
出力MSVC
Constructing!
Copy constructing!
Destructing..
before return
Destructing..
出力フィルタの図式に基づ
Constructing!
before return
Destructing..
また、この結果については、付属MSVC見間違っています。
質問
- AFAIK、GCCは正しい結果を導きます。なぜMSVCは異なる結果というコピー建設?
const foo& f = get()
やconst foo f = get()
生じ出力での戻り値を最適化するこの場合、書きすべき。
意思想..
解決
あなたのMSVCビルドが上で何の最適化を持っていません。あなたは、両方のために同一の出力を得るでしょう、それらをオンにします。
GCCは単に、デフォルトでは、一時にRVOを行っています。それは基本的にやってます:
const foo& f = foo();
MSVCではありません。それは、その後、参照結合し、内部foo
を破壊、外部への機能(コピーコンストラクタ呼び出しをエルゴを)それをコピーし、機能にfoo
を作ってます。
の両方の出力が正しいです。 RVOは標準が明示的に変更するプログラムの観察可能な行動を可能にする一つの例です。
他のヒント
のget()関数ローカル(プリントの構築を!)の構築、および値ではFooオブジェクトを返しています。返されるのFooオブジェクトを作成する必要がありますし、コピー建設を経由して行ってさ(構築コピーを印刷します!)。なお、これは主にCONSTのfoo&Fに割り当てられたオブジェクトの値である。
その割り当てがものの行われる前に、関数は、(GETから返さなければならない)とローカル変数(すなわちFOO fは、GETに())が破壊されなければなりません。 (第1の消滅を印刷..)そこからプログラムを終了する(主からすなわち復帰)を取得することによって返されたオブジェクト()と「F」に割り当てが破壊されます。 (...第二消滅を印刷する)
あなたは2つのコンパイラのために異なる出力を見ている理由は、GCCは、getの戻り値を(最適化された)と、単にconst foo &f = get()
にconst foo &f = foo
を交換していることである。
1)これは、異なる最適化戦略の起こります。あなたはconstのFOO&F(GET())ので、実行するコピーのようなものに演算子=、MSVC缶の再構築コードを持っていないのでonstructor。 2)あなたがacheiveしたいかに依存します:
const foo& f = get();
f = get(); // Incorrect, const references cannot be reassigned.
const foo g = get();
g = get(); // Correct.