標準では、関数の引数として一時的なものを渡す場合にのみ、コピー省略が許可されます。
あなたが期待している 2 つのエリシオンは、以下の太字で示されています。
[C++11: 12.8/31]:
特定の基準が満たされている場合、オブジェクトのコピー/移動コンストラクターおよび/またはデストラクタに副作用がある場合でも、実装はクラス オブジェクトのコピー/移動構築を省略できます。このような場合、実装は、省略されたコピー/移動操作のソースとターゲットを、同じオブジェクトを参照する 2 つの異なる方法として扱い、そのオブジェクトの破棄は、2 つのオブジェクトが削除されていた時間のうちの遅い方の時点で発生します。最適化なしで破壊されました。コピー省略と呼ばれるこのコピー/移動操作の省略は、次の状況で許可されます (複数のコピーを排除するために組み合わせることができます)。
- クラスの戻り値の型を持つ関数の return ステートメントで、式が関数の戻り値の型と同じ cv 非修飾型を持つ不揮発性自動オブジェクト (関数または catch-clause パラメーター以外) の名前である場合、自動オブジェクトを関数の戻り値に直接構築することにより、コピー/移動操作を省略できます
- throw 式で、オペランドが非揮発性自動オブジェクト (関数または catch 節パラメーター以外) の名前であり、そのスコープが最も内側の try ブロック (存在する場合) の末尾を超えない場合。 )、オペランドから例外オブジェクトへのコピー/移動操作(15.1)は、自動オブジェクトを例外オブジェクトに直接構築することにより省略できます
- 参照 (12.2) にバインドされていない一時クラス オブジェクトが同じ cv 非修飾型のクラス オブジェクトにコピー/移動される場合、一時オブジェクトをターゲットに直接構築することにより、コピー/移動操作を省略できます。省略されたコピー/移動の
- 例外ハンドラーの例外宣言 (条項 15) が、例外オブジェクト (15.1) と同じ型 (cv 修飾を除く) のオブジェクトを宣言する場合、例外宣言を次のように扱うことによって、コピー/移動操作を省略することができます。 exception-declaration によって宣言されたオブジェクトのコンストラクターとデストラクタの実行を除いて、プログラムの意味が変更されない場合は、例外オブジェクトのエイリアス。[..]
不揮発性の名前が関数パラメーターだったため、戻り値では発生しませんでした。
のパラメータへの構築で発生しました。create
それ以外の場合は次のようになります。
Klass()
Klass(const Klass& right)
create(Klass a)
Klass(const Klass& right)