C ++ 1zのリスト初期化では、保証されたコピーの省略はどのように機能しますか?

カルーセル

C ++ドラフトn4606 [dcl.init] 17.6には、保証されたコピーの省略に関する段落があります。

  • 宛先タイプが(おそらくcv修飾された)クラスタイプの場合:
    • イニシャライザ式がprvalueであり、ソースタイプのcv非修飾バージョンがデスティネーションのクラスと同じクラスである場合、イニシャライザ式を使用してデスティネーションオブジェクトが初期化されます。[デフォルトのコンストラクターをT x = T(T(T()));呼び出してT初期化しますx終了例]
    • [...]

それがどのように機能するかについてのQ&Aトークもあります。

私が理解しているように、私が引用したルールは、初期化式がprvalueであり、ソース型のcv非修飾バージョンが宛先のクラスと同じクラスである場合にctorが関与しないことを保証します。そのため、ctorのコピーまたは移動の存在を確認する必要はありません。これにより、次のコードがC ++ 17で有効になります。

struct A {
    A() {}
    A(A const &) = delete;
    A(A &&) = delete;
};
A f() { return A(); } // it's illegal in C++14, and suppose to be legal in C++17

しかし、私を夢中にさせるのは、c ++ドラフトn4606のリスト初期化セクションに同様のルールが見つからないことです。私が見つけたのは([dcl.init.list] 3.6)

[...]

  • それ以外の場合、Tがクラスタイプの場合、コンストラクターが考慮されます。該当するコンストラクターが列挙され、オーバーロード解決(13.3、13.3.1.7)によって最適なコンストラクターが選択されます。引数のいずれかを変換するために絞り込み変換(以下を参照)が必要な場合、プログラムの形式が正しくありません。[...]

リストの初期化は私が引用した最初のルールよりも優先度が高いため、イニシャライザーがイニシャライザーリストである場合は、リストの初期化セクションのルールを検討する必要があります。ご覧のとおり、クラスタイプをリスト初期化するときにコンストラクターが考慮されTます。したがって、前の例に続き、

A ff() { return {A()}; }

C ++ 17で合法ですか?そして、誰かが標準ドラフトがリストの初期化で保証されたコピーの省略がどのように機能するかを指定している場所を見つけることができますか?

ニコル・ボーラス

保証された省略は、prvalue式を「オブジェクトを初期化する」ことを意味するように再定義することによって機能します。彼らはもはや一時的なものを構築しません。代わりに、一時変数、prvalue式の特定の使用によって構築されます。

上記の「表現」という言葉の頻繁な使用に注意してください。1つの非常に重要な事実のために指摘します:braced-init-listは式ではありません。規格はこれについて非常に明確です。それは式ではない、とだけ表現はprvaluesすることができます。

確かに、エリジオンに関する規格のセクションを検討してください。

コピーの省略と呼ばれるこのコピー/移動操作の省略は、次の状況で許可されます。

  • が非揮発性の自動オブジェクトの名前である場合、クラスの戻り値の型を持つ関数のreturnステートメントで...
  • ..。
  • 参照(12.2)にバインドされていない一時クラスオブジェクトが、同じcv-unqualifiedタイプのクラスオブジェクトにコピー/移動される場合

これらはすべて式を含みます(一時クラスオブジェクトは式です)。Braced-init-listsは式ではありません。

そのため、を発行した場合、が何であるかに関係なく、return {anything};からの戻り値の構築はanything省略されませんanythingもちろん、標準によると、コンパイラはバグにより異なる場合があります。

そうは言っても、戻り値と同じ型のprvalue式がある場合、return {prvalue};だけでなく入力する可能性はほとんどありませんreturn prvalue;また、式が別のタイプである場合、とにかく省略の対象にはなりません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

「保証されたコピーの省略」(P0135、C ++ 1z)は潜在的にABIの破損を必要としますか?

分類Dev

中括弧を使用したコピーの初期化により、C ++でのコピー/移動の構築が省略されるのはなぜですか?

分類Dev

C ++ 14およびC ++ 1zの機能を使用して、この可変個引数テンプレートコードを短くするにはどうすればよいですか?

分類Dev

ネストされたforループはC#でどのように機能しますか

分類Dev

C ++のコピーの省略中にメモリはどのように管理されますか?

分類Dev

均一なブレース配列の初期化のための保証されたコピーの省略-C ++ 17以降、これは必須ではありませんか?

分類Dev

宣言時の新しいC ++ 11メンバー初期化機能により、初期化リストは廃止されましたか?

分類Dev

C ++のコピーコンストラクターはどのように機能しますか?

分類Dev

C ++ 1zは言語機能をコルーチン化しますか?

分類Dev

ストリーム入力は、cinを使用したC ++でどのように機能しますか?

分類Dev

c#自分でコンストラクターを提供しない場合、フィールドはどのように初期化されますか?

分類Dev

C ++は、ヘッダーで初期化された静的constメンバーが、コンパイルユニットとライブラリ間で単一のインスタンスを共有することを保証しますか?

分類Dev

C#のソートされたセットはカスタムオブジェクトでどのように機能しますか?

分類Dev

このC ++コードは常に期待どおりに機能しますか、それとも実行順序は保証されませんか?

分類Dev

テンプレートテンプレートの部分的特殊化は、-std = c ++ 1zとg ++でのみ機能します

分類Dev

構造体配列のコピーはCでどのように機能しますか?

分類Dev

イテレータはC ++のリストでどのように機能しますか?

分類Dev

構造はCで内部的にどのように機能しますか?ある構造から別の構造へのデータコピーはどのように作成されますか?

分類Dev

ブレースで囲まれたリストの初期化子の数が、集合体の要素またはメンバーの数よりも少ない場合、Cコンパイラはどのように配列を宣言しますか?

分類Dev

移動コンストラクターはC ++でどのように機能しますか?

分類Dev

C ++ 11の空のリストユニオンの初期化-ユニオンの全長を初期化することは保証されていますか?

分類Dev

C#でループを使用してリストのサイズを保証するにはどうすればよいですか?

分類Dev

NodeクラスのリンクリストはC ++でどのように機能しますか?

分類Dev

コンパイラによって配列はCでどのように初期化(ゼロ)されますか?

分類Dev

C#の整数のリストなどの初期化されていないジェネリックコレクションのorderby降順句を実現するためにクエリを作成するにはどうすればよいですか?

分類Dev

C#のキューでどのように機能しますか?(許可されるタイプ、初期化およびフィールド)

分類Dev

C ++ 20以降、コンストラクターが明示的にデフォルトまたは削除されている場合、集約の初期化が機能しなくなるのはなぜですか?

分類Dev

C Sharp仕様の実装は、静的コンストラクターがスレッドセーフな方法で実行されることをどのように保証しますか?

分類Dev

C ++ 17およびemplace_back(...)でのコピーの省略が保証されています

Related 関連記事

  1. 1

    「保証されたコピーの省略」(P0135、C ++ 1z)は潜在的にABIの破損を必要としますか?

  2. 2

    中括弧を使用したコピーの初期化により、C ++でのコピー/移動の構築が省略されるのはなぜですか?

  3. 3

    C ++ 14およびC ++ 1zの機能を使用して、この可変個引数テンプレートコードを短くするにはどうすればよいですか?

  4. 4

    ネストされたforループはC#でどのように機能しますか

  5. 5

    C ++のコピーの省略中にメモリはどのように管理されますか?

  6. 6

    均一なブレース配列の初期化のための保証されたコピーの省略-C ++ 17以降、これは必須ではありませんか?

  7. 7

    宣言時の新しいC ++ 11メンバー初期化機能により、初期化リストは廃止されましたか?

  8. 8

    C ++のコピーコンストラクターはどのように機能しますか?

  9. 9

    C ++ 1zは言語機能をコルーチン化しますか?

  10. 10

    ストリーム入力は、cinを使用したC ++でどのように機能しますか?

  11. 11

    c#自分でコンストラクターを提供しない場合、フィールドはどのように初期化されますか?

  12. 12

    C ++は、ヘッダーで初期化された静的constメンバーが、コンパイルユニットとライブラリ間で単一のインスタンスを共有することを保証しますか?

  13. 13

    C#のソートされたセットはカスタムオブジェクトでどのように機能しますか?

  14. 14

    このC ++コードは常に期待どおりに機能しますか、それとも実行順序は保証されませんか?

  15. 15

    テンプレートテンプレートの部分的特殊化は、-std = c ++ 1zとg ++でのみ機能します

  16. 16

    構造体配列のコピーはCでどのように機能しますか?

  17. 17

    イテレータはC ++のリストでどのように機能しますか?

  18. 18

    構造はCで内部的にどのように機能しますか?ある構造から別の構造へのデータコピーはどのように作成されますか?

  19. 19

    ブレースで囲まれたリストの初期化子の数が、集合体の要素またはメンバーの数よりも少ない場合、Cコンパイラはどのように配列を宣言しますか?

  20. 20

    移動コンストラクターはC ++でどのように機能しますか?

  21. 21

    C ++ 11の空のリストユニオンの初期化-ユニオンの全長を初期化することは保証されていますか?

  22. 22

    C#でループを使用してリストのサイズを保証するにはどうすればよいですか?

  23. 23

    NodeクラスのリンクリストはC ++でどのように機能しますか?

  24. 24

    コンパイラによって配列はCでどのように初期化(ゼロ)されますか?

  25. 25

    C#の整数のリストなどの初期化されていないジェネリックコレクションのorderby降順句を実現するためにクエリを作成するにはどうすればよいですか?

  26. 26

    C#のキューでどのように機能しますか?(許可されるタイプ、初期化およびフィールド)

  27. 27

    C ++ 20以降、コンストラクターが明示的にデフォルトまたは削除されている場合、集約の初期化が機能しなくなるのはなぜですか?

  28. 28

    C Sharp仕様の実装は、静的コンストラクターがスレッドセーフな方法で実行されることをどのように保証しますか?

  29. 29

    C ++ 17およびemplace_back(...)でのコピーの省略が保証されています

ホットタグ

アーカイブ