35

標準で許可されていますか:

struct A
{
  int a = 3;
  int b = 3;
};

A a{0,1}; // ???

このクラスはまだ集約されていますか? clangはこのコードを受け入れますが、受け入れgccません。

4

1 に答える 1

44

C++11 では、クラス内メンバー初期化子を使用すると、構造体/クラスが集合体ではなくなります — ただし、これは C++14 で変更されました。これは、私が最初に遭遇したときに驚くべきことでした。この制限の論理的根拠は、クラス内初期化子がユーザー定義のコンストラクターに非常に似ているということですが、反論は、クラス内初期化子を追加することで彼らのクラス/構造体は非集合体ですが、そうではありませんでした。

ドラフト C++11 標準セクション8.5.1 Aggregatesから(今後の強調):

集合体は、ユーザー提供のコンストラクター (12.1) を持たない配列またはクラス (条項 9)、非静的データ メンバーのブレースまたはイコール初期化子(9.2)、プライベートまたは保護された非静的データ メンバー (条項11)、基本クラスなし (条項 10)、および仮想関数なし (10.3)。

C++14 では、同じ段落に次のように書かれています。

集約は、ユーザー提供のコンストラクター (12.1)、プライベートまたは保護された非静的データ メンバー (条項 11)、基本クラス (条項 10)、および仮想関数 (10.3) を持たない配列またはクラス (条項 9) です。 )。

この変更はN3605でカバーされています: 次の要約を持つメンバー初期化子と集約:

Bjarne Stroustrup と Richard Smith は、集約の初期化とメンバー初期化子が連携しないという問題を提起しました。この論文では、Smith が提案した文言を採用することで、この問題を解決することを提案しています

このコメントは基本的に、それらを集約にすることへの抵抗を要約しています。

集合体はユーザー定義のコンストラクターを持つことができず、 メンバー初期化子は本質的にある種のユーザー定義のコンストラクター (要素)です (コア欠陥 886 も参照してください)。私はこの拡張に反対しているわけではありませんが、集計のモデルが実際に何であるかにも影響があります。この拡張機能を受け入れた後、集計とは何かを教える方法を知りたいです。

改訂版N3653は2013 年 5 月に採用されました。

アップデート

emsr は、 G++ 5.0 が、 または のいずれかを使用する非静的データ メンバー初期化子を持つ C++14 集計をサポートするようになったことを指摘しています。std=c++1y-std=c++14

struct A { int i, j = i; };
A a = { 42 }; // a.j is also 42

ライブで動作するのを見てください。

于 2014-11-25T03:52:55.373 に答える