2017-11-30 6 views
2

次のコードはなぜコンパイルされませんか?なぜ初期化子リストをブレースしたコンストラクタ/仮想デストラクタが機能しないのですか?

#include <vector> 

class Foo 
{ 
public: 
    Foo() 
    { } 

    virtual ~Foo() 
    { } 

    std::vector<int> aVec; 
}; 


Foo bar = 
{ 
    { 1, 2, 3, 4, 5 } 
}; 

次のコードはコンパイルされている間:

#include <vector> 

class Foo 
{ 
public: 

    /*Foo() 
    { } 

    virtual*/ ~Foo() 
    { } 

    std::vector<int> aVec; 
}; 


Foo bar = 
{ 
    { 1, 2, 3, 4, 5 } 
}; 

言語規則を参照するとともに、それらの規則の根拠について詳しく説明してください。

コンストラクタと仮想デストラクタの存在が初期化を停止するのはなぜですか?

+4

コンパイルエラーについては、コンパイラエラーを含めてください。 – BoBTFish

+0

クラスコンストラクタを無視しようとしていますか? – curiousguy

答えて

5

Fooはクラスタイプであるため、ブレースされたinitリストはaggregate initializationと見なされます。これは、クラスが明示的なコンストラクタや仮想メンバーを持っていないこと、とりわけ、必要があります。

集計初期化が が凝集体を初期化リスト初期化の形態です。集計は、次のいずれかのタイプである:あり

クラスタイプ(一般的に、構造体または共用体)、...

  • なしプライベートまたは保護された非静的データメンバ

  • なし(C++ 17以降)ユーザが提供する、継承された、または明示的なコンストラクタ(明示的にデフォルト設定または削除コンストラクタは許可されている)

  • なし、仮想プライベート、または保護された基底クラス
  • なしV irtualメンバ関数
  • デフォルトのメンバー初期化子
5

使用しているリストの初期化の形がaggregate initializationとして知られています。集約型に使用されます。型が集約として修飾するための要件の1つは、ユーザーが提供するコンストラクタがないことです。

コンパイラは、リストの初期化を定義されたコンストラクタの1つに一致させようとします。それは単一のを取るコンストラクタを好むでしょうstd::initializer_list。あなたが提供していないので、初期化リストによって提供されるものと引数が一致するコンストラクタを見つけることを試みます。唯一のコンストラクタは引数を取らないデフォルトのコンストラクタなので、一致するものは見つかりません。

1

Foo bar = { { 1, 2, 3, 4, 5 } };は、aggregate initializationである。配列と集約クラスの型に対してのみ定義されています。コンストラクタまたは仮想メンバーを追加すると、そのタイプは集約ではありません。

関連する問題