は、私は次の最適化が期待どおりに動作かどうかを確認したかった:コピーエリートの条件は?
- RVO RVO名前
は、だから私はこの小さなプログラムを書いた値で引数を渡すときに
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <vector>
struct Foo {
Foo(std::size_t length, char value) : data(length, value) { }
Foo(const Foo & rhs) : data(rhs.data) { std::cout << "*** COPY ***" << std::endl; }
Foo & operator= (Foo rhs) {
std::cout << "*** ASSIGNMENT ***" << std::endl;
std::swap(data, rhs.data); // probably expensive, ignore this please
return *this;
}
~Foo() { }
std::vector<char> data;
};
Foo TestRVO() { return Foo(512, 'r'); }
Foo TestNamedRVO() { Foo result(512, 'n'); return result; }
void PassByValue(Foo inFoo) {}
int main()
{
std::cout << "\nTest RVO: " << std::endl;
Foo rvo = TestRVO();
std::cout << "\nTest named RVO: " << std::endl;
Foo named_rvo = TestNamedRVO();
std::cout << "\nTest PassByValue: " << std::endl;
Foo foo(512, 'a');
PassByValue(foo);
std::cout << "\nTest assignment: " << std::endl;
Foo f(512, 'f');
Foo g(512, 'g');
f = g;
}
そして、最適化enエーブル:
Test RVO:
Test named RVO:
Test PassByValue:
*** COPY ***
Test assignment:
*** COPY ***
*** ASSIGNMENT ***
出力RVOと予想通りという名前RVO作業によると:
$ g++ -o test -O3 main.cpp ; ./test
これが出力されます。ただし、代入演算子とPassByValue
を呼び出す場合は、コピーエリートは実行されません。
ユーザ定義のコピーコンストラクタでcopy elisionを使用できませんか? (私は、RVOが標準で明示的に許可されていることを知っていますが、値渡しの際にはコピーエリジョンについて知らないのです)コピーコンストラクタを定義せずにコピーエリッションを検証する方法はありますか?
(N)RVO *は*コピーエリートです。それらは唯一の形式ではありませんが、あなたの例では、コピーエリジョンが実行されていないことが不正確であることを示しています。 –
Cooy elisionは、一般にすべての一時的なオブジェクトに対して許可されますが、名前付きオブジェクトまたは参照対象オブジェクトには許可されません。 gccは許可されたものを正確に実行するようです。 –
@Dennis Zickefooseありがとう、私はテキストを修正しました。 – StackedCrooked