C ++ 17で空のリスト初期化コンストラクターを使用するとコンパイルエラーが発生する

RyArazi

C ++ 17に移行しようとすると、奇妙な問題が発生しました。問題は、C ++ 17で何か(そして何がわからないか)が変更され、デフォルトのコンストラクターの場合にリストの初期化の動作が異なることです。https://en.cppreference.com/w/cpp/language/list_initializationで詳細を検索しようとしましたが、関連性のあるものは見つかりませんでした。

以下のコードがC ++ 14でコンパイルされるが、B{}代わりに呼び出すときにC ++ 17でコンパイルされない理由を誰かが知っていますかB()(gcc8.2と7.3およびicc19の両方で試しました)

struct A{
protected:
    A() {}
};

struct B : public A {};


B f(){
    return B(); //compilation OK
    //return B{}; //compilation error
}
バリー

C ++ 14では、集計定義は次のとおりです。

集合体は、ユーザー提供のコンストラクター([class.ctor])、プライベートまたは保護された非静的データメンバー(Clause [class.access])、基本クラスClause [class.access])を含まない配列またはクラス(Clause [class])です。句[class。派生])、および仮想関数なし([class.virtual])。

したがって、Bは集合体はありません。その結果、B{}確実に集約初期設定ではなく、B{}B()同じことを意味してしまいます。どちらも、Bのデフォルトコンストラクタを呼び出すだけです。

ただし、C ++ 17では、集計定義が次のように変更されました。

骨材は、アレイまたはクラスであります

  • ユーザー提供、明示的、または継承されたコンストラクター([class.ctor])はありません。
  • プライベートまたは保護された非静的データメンバーがない([class.access]節)、
  • 仮想関数なし、および
  • 仮想、プライベート、または保護された基本クラス([class.mi])はありません

[注:集計の初期化では、保護されたプライベート基本クラスのメンバーまたはコンストラクターにアクセスできません。  —エンドノート]

制限はもはやオンになっていない任意のちょうど仮想/プライベート/保護されたもので、基底クラス。しかしB、パブリックベースクラスがあります。集合体になりました!また、C ++ 17集約初期化では、基本クラスのサブオブジェクトを初期化できます。

特に、B{}サブオブジェクトの初期化子を提供しない集約初期化です。しかし、最初の(そして唯一の)サブオブジェクトは、A初期化しようとしているからです{}(集計の初期化中に、明示的な初期化子のないサブオブジェクトはからコピー初期化されます{})。これは、Aコンストラクターが保護されているため実行できません。私たちは友達ではありません(引用されたメモも参照してください)。


楽しみのために、C ++ 20ではaggregate定義が再び変更されることに注意してください

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

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

編集
0

コメントを追加

0

関連記事

分類Dev

C ++ 17で空のリスト初期化コンストラクターを使用するとコンパイルエラーが発生する

分類Dev

llvm-Cコードでmemcpyを使用し、wasmターゲットでコンパイルするとリンクエラーが発生します

分類Dev

C ++でメンバーのコンストラクターパラメーターを初期化する方法

分類Dev

C ++でコンストラクターを使用してクラスから継承しようとするとエラーが発生します

分類Dev

dev c ++を使用していますが、エラーが発生します(C ++ 98の「配列」はコンストラクターで初期化する必要があります)

分類Dev

初期化リストを使用するときにコンストラクターに渡されるパラメーターを確認します-C ++

分類Dev

別のクラスのtypedefされたメンバーを使用すると、C ++コンパイルエラーが発生します

分類Dev

C ++のコンストラクターでc配列を初期化する際のエラー

分類Dev

Objective Cのパラメータ化されたコンストラクタでNSDateを初期化する方法は?

分類Dev

C ++ Boost:コンストラクターの後にエンドポイントを初期化する

分類Dev

rbenvを使用してRuby2.5.1をインストールできず、Cコンパイラエラーが発生する

分類Dev

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

分類Dev

コンストラクターc ++で属性を初期化する際の問題

分類Dev

C ++の初期化子リストとクラスの初期化。引数なしのコンストラクターがありますが、初期化リストを使用する必要がありますか?

分類Dev

C ++の初期化子リストとクラスの初期化。引数なしのコンストラクターがありますが、初期化リストを使用する必要がありますか?

分類Dev

Visual C ++ 2010コンパイラでcode :: blockでウィジェットライブラリを使用すると、エラーが発生します

分類Dev

C ++のコンストラクターを使用して2Dベクトルを初期化する方法は?

分類Dev

リンクリストc ++でクラスを試行するとエラーが発生する

分類Dev

C ++ 11:デフォルトのコンストラクターをデフォルトにすると、クラスが部分的に初期化されますか?

分類Dev

memmoveを使用してC ++のコンストラクターでオブジェクト全体を初期化する

分類Dev

エラーC2512:適切なデフォルトコンストラクターが利用できません-プロパティがコンストラクターで初期化されているのはなぜですか?

分類Dev

関数を削除するとCのリンクリストでエラーが発生する理由

分類Dev

C ++エラー:の初期化に一致するコンストラクターがありません

分類Dev

C ++ 17の別のコンストラクターとは異なる引数タイプでコンストラクターを呼び出す

分類Dev

ポインタ(C ++)を使用すると、初期化されていないヒープメモリエラーが発生するのはなぜですか?

分類Dev

C ++でクラスをコンパイルするときのエラー

分類Dev

C ++ 11コンパイラでのコンストラクタの継承でエラーが発生しています

分類Dev

ベクトル型のクラスのプライベートメンバーをコンパイルするときにエラーが発生しました-C ++

分類Dev

C ++ 11スタイルでオブジェクトの配列を初期化しようとしているときに、コンパイラがコンストラクタを暗黙的に削除する理由

Related 関連記事

  1. 1

    C ++ 17で空のリスト初期化コンストラクターを使用するとコンパイルエラーが発生する

  2. 2

    llvm-Cコードでmemcpyを使用し、wasmターゲットでコンパイルするとリンクエラーが発生します

  3. 3

    C ++でメンバーのコンストラクターパラメーターを初期化する方法

  4. 4

    C ++でコンストラクターを使用してクラスから継承しようとするとエラーが発生します

  5. 5

    dev c ++を使用していますが、エラーが発生します(C ++ 98の「配列」はコンストラクターで初期化する必要があります)

  6. 6

    初期化リストを使用するときにコンストラクターに渡されるパラメーターを確認します-C ++

  7. 7

    別のクラスのtypedefされたメンバーを使用すると、C ++コンパイルエラーが発生します

  8. 8

    C ++のコンストラクターでc配列を初期化する際のエラー

  9. 9

    Objective Cのパラメータ化されたコンストラクタでNSDateを初期化する方法は?

  10. 10

    C ++ Boost:コンストラクターの後にエンドポイントを初期化する

  11. 11

    rbenvを使用してRuby2.5.1をインストールできず、Cコンパイラエラーが発生する

  12. 12

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

  13. 13

    コンストラクターc ++で属性を初期化する際の問題

  14. 14

    C ++の初期化子リストとクラスの初期化。引数なしのコンストラクターがありますが、初期化リストを使用する必要がありますか?

  15. 15

    C ++の初期化子リストとクラスの初期化。引数なしのコンストラクターがありますが、初期化リストを使用する必要がありますか?

  16. 16

    Visual C ++ 2010コンパイラでcode :: blockでウィジェットライブラリを使用すると、エラーが発生します

  17. 17

    C ++のコンストラクターを使用して2Dベクトルを初期化する方法は?

  18. 18

    リンクリストc ++でクラスを試行するとエラーが発生する

  19. 19

    C ++ 11:デフォルトのコンストラクターをデフォルトにすると、クラスが部分的に初期化されますか?

  20. 20

    memmoveを使用してC ++のコンストラクターでオブジェクト全体を初期化する

  21. 21

    エラーC2512:適切なデフォルトコンストラクターが利用できません-プロパティがコンストラクターで初期化されているのはなぜですか?

  22. 22

    関数を削除するとCのリンクリストでエラーが発生する理由

  23. 23

    C ++エラー:の初期化に一致するコンストラクターがありません

  24. 24

    C ++ 17の別のコンストラクターとは異なる引数タイプでコンストラクターを呼び出す

  25. 25

    ポインタ(C ++)を使用すると、初期化されていないヒープメモリエラーが発生するのはなぜですか?

  26. 26

    C ++でクラスをコンパイルするときのエラー

  27. 27

    C ++ 11コンパイラでのコンストラクタの継承でエラーが発生しています

  28. 28

    ベクトル型のクラスのプライベートメンバーをコンパイルするときにエラーが発生しました-C ++

  29. 29

    C ++ 11スタイルでオブジェクトの配列を初期化しようとしているときに、コンパイラがコンストラクタを暗黙的に削除する理由

ホットタグ

アーカイブ