これは temp からのコピーであるため、最適化される可能性があり、おそらく最適化されるでしょう。
ここでのキーワードはおそらく. 標準では、コンパイラがコピーを最適化することは許可されていますが、必須ではありません。一部のコンパイラがこのコードを許可 (最適化) し、他のコンパイラが拒否 (非最適化) した場合、これは非常に矛盾したものになります。
したがって、標準では、これを処理する一貫した方法が規定されています。使用するかどうかに関係なく、誰もがコピー コンストラクターにアクセスできることを確認する必要があります。
アイデアは、すべてのコンパイラがコードを受け入れるか拒否する必要があるということです。そうしないと、移植できなくなります。
別の例を考えてみましょう
A a;
B b;
A a1 = a;
A a2 = b;
s コピー コンストラクターがプライベートの場合、許可することとa2
禁止することは、同様に一貫性がありません。a1
A
標準テキストから、クラス オブジェクトを初期化する 2 つの方法が異なることを意図していたこともわかります (8.5/16)。
初期化が直接初期化の場合、またはソース型の cv 修飾されていないバージョンが宛先のクラスと同じクラスまたは派生クラスであるコピー初期化の場合、コンストラクターが考慮されます。適用可能なコンストラクターが列挙され (13.3.1.3)、オーバーロード解決 (13.3) によって最適なコンストラクターが選択されます。そのように選択されたコンストラクターは、初期化式または式リストを引数として使用して、オブジェクトを初期化するために呼び出されます。コンストラクターが適用されない場合、またはオーバーロードの解決があいまいな場合、初期化は不適切な形式です。
それ以外の場合 (つまり、残りのコピー初期化の場合)、ソース型から宛先型に、または (変換関数が使用されている場合は) その派生クラスに変換できるユーザー定義の変換シーケンスは、13.3 で説明されているように列挙されます。 1.4 であり、過負荷解決 (13.3) によって最適なものが選択されます。変換ができないか、あいまいな場合は、初期化の形式が正しくありません。選択された関数は、初期化式を引数として呼び出されます。関数がコンストラクターの場合、呼び出しは、目的の型の cv 修飾されていないバージョンの一時を初期化します。一時的なものは prvalue です。呼び出しの結果 (コンストラクターの場合は一時的なもの) は、上記の規則に従って、コピー初期化の宛先であるオブジェクトを直接初期化するために使用されます。場合によっては、中間結果を初期化されるオブジェクトに直接構築することにより、この直接初期化に固有のコピーを排除する実装が許可されます。12.2、12.8を参照。
違いは、直接初期化が構築されたクラスのコンストラクターを直接使用することです。コピー初期化では、他の変換関数が考慮され、これらはコピーする必要がある一時を生成する場合があります。