6

以下の例では、既定のコンストラクタが明示的に削除されている(またはその既定になっている)にもかかわらず、集約の初期化が可能であることに驚きました。集約初期化でコンストラクタへのアクセスが維持されない

#include <iostream> 

struct DefaultPrivate 
{ 
     const int n_; 
     static const DefaultPrivate& create(); 

    private: 
     DefaultPrivate() = delete; 
}; 

const DefaultPrivate& DefaultPrivate::create() 
{ 
    static DefaultPrivate result{10}; 
    return result; 
} 

int main() { 
    DefaultPrivate x; //Fails 
    DefaultPrivate y{10};//Works 
    return 0; 
} 

プライベートデフォルト(または削除済み)構成と集約初期化の間の関係は、標準では指定されていませんか?

これは、GCC 6.3およびVCC 2017の両方の場合

私は質問をしていた理由だった私は、既定のコンストラクタへのアクセスを変更するとCから公開集約の初期化

+0

私の謝罪、私は気づいたと、その部分を削除します。私はhファイルを修正し、何らかの理由で私のcppファイルが再コンパイルされなかった –

答えて

4

を防ぐことを期待ということでした++ 11、T集約型の場合list initialization

ため、集計初期化が行われます。

そして、C++ 11 aggregate次のいずれかのタイプであると:

    を持って

    ...

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

  • ...

  • ユーザー提供なしC++ 11から意味のコンストラクタ(explicitly defaulted or deleted constructors are allowed) (since C++11)

  • ...

は、明示的に削除されたコンストラクタを持つクラスは、依然として、次いで凝集初期化が許可され、集合型と考えられます。

効果がある:

direct public base, (since C++17)配列要素、または非静的クラスメンバーは、クラス定義の配列添字/出現順に、コピー初期化初期の対応する句からですリスト。 DefaultPrivate y{10};のために、上記のプロセスでは、既定のコンストラクタは、それがdeleteprivateとして宣言だという事実は重要ではありません、全く考慮されないことを

注意。

BTW

DefaultPrivate x;default initialization行われる、

T場合は、コンストラクタが考慮され、空の引数リストに対して解像度を過負荷にさらされる、non-POD (until C++11)クラスタイプです。選択されたコンストラクタ(デフォルトコンストラクタの1つ)は、新しいオブジェクトの初期値を提供するために呼び出されます。

デフォルトのコンストラクタが使用されていますが、delete edの場合、コンパイルは失敗します。

DefaultPrivate x{};のような集約初期化を使用すると、コードも正常に動作します。 n_value initialized(次にzero initialized)は0となります。

LIVE

+0

はい、タイプは集約ですが、それは私的な意味で集約されています。そうでなければ、私は集約を使用しませんでしたタイトル: –

+1

@WernerErasmus回答が改訂されました。要は、このケースではコンストラクタは考慮されないため、問題ではありません。 – songyuanyao

関連する問題