正しい答えは、あなたが話しているC++標準によって異なります。
C++ 11について言えば、clangは正しい(明示的な移動が必要です)。 C++ 14について話している場合、gccは正しい(明示的な移動は必要ありません)。
C++ 11には、N3290/[class.copy]/P32で述べている:
When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If overload resolution fails, ...
これは、リターン式が関数の戻り値の型と同じ型を持っているときにのみ、暗黙的な動きを得ることを求めています。
しかし、CWG 1579がこれを変更しました。この欠陥レポートはC++ 11以降、C++ 14以降で受け入れられました。この同じ段落は今読み:
When the criteria for elision of a copy/move operation are met, but not for an exception-declaration, and the object to be copied is designated by an lvalue, or when the expression in a return
statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If the first overload resolution fails or was not performed, ...
をこの変更は、基本的には、return式の型がコンバーチブル-する関数の戻り値の型を、まだ暗黙の移動のための資格を得ることができるようになります。
これは、__cplusplus
の値に基づいてコードに#if
/#else
が必要であることを意味しますか?
私はそれをすることができますが、私は気にしません。私はC++ 14をターゲットにしていた場合、私はちょうどになります。コードが予期せずC++ 11コンパイラの下で実行されている場合は
return i;
、エラーのコンパイル時に通知されます、そして、それは簡単です修正する:
return std::move(i);
をあなただけのC++ 11をターゲットにしている場合は、move
を使用しています。
C++ 11とC++ 14(およびそれ以降)の両方をターゲットにする場合は、move
を使用してください。 move
を不必要に使用することの欠点は、RVO(戻り値の最適化)を禁止できることです。ただし、この場合、RVOは法的ではありません(return
文から関数の戻り型に変換されるため)。そして、無償のmove
は何も傷つけません。
それなしで、物事はまだC++ 11でコンパイル、および動きとは反対に、高価なコピー変換を起動する場合は、C++ 14をターゲットにしても無償move
方に傾く可能性がある1時間があります変換。この場合、誤ってC++ 11でコンパイルすると、静かなパフォーマンスバグが発生します。また、C++ 14でコンパイルした場合、無償のmove
には依然として有害な影響はありません。
私は、あなたが必要とするものを理解したときに、より良い答えを出すことができると考えています。現時点では、これはmake_uniqueの代わりにmake_sharedを呼び出すことで簡単に解決できます。それが不可能な理由があると仮定し、その理由を理解するのに役立ちます。 – Elliott
@Elliott:何が解決できるのですか?彼は何かを解決する方法を尋ねていない、彼は彼が持っているコードが標準で正しいかどうか尋ねている。 –