次のコードがあるとしましょう。
#include <iostream>
#include <string>
struct A
{
A() {}
A(const A&) { std::cout << "Copy" << std::endl; }
A(A&&) { std::cout << "Move" << std::endl; }
std::string s;
};
struct B
{
A a;
};
int main()
{
B{A()};
}
ここで、構造体にA
は自明ではないコンストラクターと、集合体ではないと思われるstd::string
メンバーの両方があるため、構造体は集合体ではないと思います。これはおそらくB
、 も集合体ではないことを意味します。
それでも、initialize B を集約できます。さらに、これは、copy コンストラクターも move コンストラクターも呼び出されずに実行できます (例: C++0x GCC 4.5.1 on ideone )。
この動作は、特に安価な動きを持たない大きなスタック タイプを一緒に構成する場合に、便利な最適化のように思えます。
私の質問は、C++0x でこの種の集計初期化が有効になるのはいつですか?
編集 + フォローアップの質問:
以下のDeadMGは次のように答えました:
これは集合体の初期化ではなく、均一な初期化です。これは基本的に、この場合はコンストラクターを呼び出すことを意味し、コピーや移動はおそらく RVO と NRVO によって行われます。
B
次のように変更すると、次のことに注意してください。
struct B
{
A a;
B(const A& a_) : a(a_) {}
B(A&& a_) : a(std::move(a_)) {}
};
移動が実行されます。
したがって、これが単なる均一な初期化であり、コンストラクターを呼び出すだけで特別なことを何もしない場合、移動を省略できるコンストラクターをどのように作成すればよいでしょうか?
それとも、GCC は、有効な場合にここで移動を省略していないだけですか? もしそうなら、移動を省略できるコンパイラと最適化の設定はありますか?