C++11 標準では、コピー省略の条件が満たされた場合 ( §12.8/31
)、実装はreturn
ed ローカル左辺値変数と関数パラメーターを最初に右辺値として扱い (移動)、オーバーロードの解決が成功しない場合は次のように処理する必要があると述べています。その後、それを左辺値 (コピー) として扱います。
§12.8 [class.copy] p32
コピー操作の省略の基準が満たされているか、ソース オブジェクトが関数パラメーターであり、コピーされるオブジェクトが左辺値によって指定されているという事実を除いて満たされる場合、コピーのコンストラクターを選択するためのオーバーロードの解決は次のとおりです。オブジェクトが rvalue によって指定されたかのように最初に実行されます。オーバーロードの解決が失敗した場合、または選択されたコンストラクターの最初のパラメーターの型がオブジェクトの型 (おそらく cv 修飾) への右辺値参照でない場合、オブジェクトを左辺値と見なしてオーバーロードの解決が再度実行されます。[注:この 2 段階のオーバーロード解決は、コピーの省略が発生するかどうかに関係なく実行する必要があります。省略が実行されない場合に呼び出されるコンストラクターを決定し、呼び出しが省略された場合でも、選択されたコンストラクターにアクセスできる必要があります。—終わりのメモ]
これにはメンバー サブオブジェクトも含まれますか? 次のスニペットでテストしました。
#include <iostream>
struct traced{
traced(){ std::cout << "default ctor\n"; }
traced(traced const&){ std::cout << "copy ctor\n"; }
traced(traced&&){ std::cout << "move ctor\n"; }
};
struct X{
traced t;
};
traced f(){
X x;
return x.t;
}
int main(){
traced t = f();
}
Ideone での実例。 また、GCC 4.7 ToT も Clang 3.1 ToT も「move ctor」を表示しないため、標準にはメンバー サブオブジェクトが含まれていないと思われます。
私は何かを見落としましたか?私のテストコードは壊れていますか? 出力がそのままになる正確な原因は何ですか?