いいえ、直接return t;
です。ケースクラスT
で
は削除されませんコンストラクタを移動している、と予告t
は、それがreturn std::move(t);
がするよう構造に返されたオブジェクトを移動return t
は、コピーの省略の対象であることをローカル変数です。しかし、return t;
は引き続きelisionのコピー/移動の対象となるため、構造を省略することがありますが、return std::move(t)
は常にムーブコンストラクタを使用して戻り値を作成します。
クラスT
の移動コンストラクタは削除されていますが、コピーコンストラクタが使用可能な場合、return std::move(t);
はコンパイルされず、return t;
はまだコピーコンストラクタを使用してコンパイルされます。上記の@Kerrekとは異なり、t
は右辺値参照にバインドされていません。コピーエリートの対象となる戻り値には、2段階のオーバーロード解決があります。最初に移動してからコピーし、移動とコピーの両方が省略される可能性があります。 return
式が、あなたはまだコピーを避けたい(あなたは非ローカル変数または左辺値式が戻ってきている可能性が高い)左辺値とコピーの省略の対象とされていない場合
class T
{
public:
T() = default;
T (T&& t) = delete;
T (const T& t) = default;
};
T foo()
{
T t;
return t; // OK: copied, possibly elided
return std::move(t); // error: move constructor deleted
return static_cast<T&>(t); // OK: copied, never elided
}
、std::move
は有用であろう。しかし、ベスト・プラクティスは、コピー・エリジョンを起こすことが可能であることを覚えておいてください。
class T
{
public:
T() = default;
T (T&& t) = default;
T (const T& t) = default;
};
T bar(bool k)
{
T a, b;
return k ? a : b; // lvalue expression, copied
return std::move(k ? a : b); // moved
if (k)
return a; // moved, and possibly elided
else
return b; // moved, and possibly elided
}
12.8(32)は、プロセスを記述しています。コピー操作のエリジオンの基準が満たされているか、ソースオブジェクトが関数のパラメータであるという事実のために保存満たされるであろう、そして物体があると
12.8 [class.copy]
32コピーは左辺値で指定され、コピーのコンストラクタを選択するオーバーロードの解像度は、オブジェクトが右辺値によって指定されたかのようにまず実行されます。オーバーロードの解決が失敗した場合、または選択されたコンストラクタの最初のパラメータの型がオブジェクトの型(おそらくcv修飾されたもの)への参照値でない場合は、オブジェクトを左辺値と見なして再度オーバーロードの解決が行われます。 [注:この2段階の過負荷解析は、コピーエリミッションが発生するかどうかに関係なく実行する必要があります。 elisionが実行されなかった場合に呼び出されるコンストラクタを決定し、選択されたコンストラクタは、呼び出しが省略されてもアクセス可能でなければなりません。 -end note]
[こちら](http://stackoverflow.com/questions/9827183/why-am-i-allowed-to-copy-unique-ptr)も同様の質問 –
[関連FAQ] (http://stackoverflow.com/a/11540204/252000) – fredoverflow