問題はaggregate initializationとなります。struct X
は集計で、struct Y
はそうではありません。
集計は、ユーザー提供のコンストラクタ(12.1)を持たない配列またはクラス(12.1)であり、brace-or-equal-initializersはありません。非静的データメンバー(9.2)、非公開または保護された非静的データメンバー(11章)、基本クラスなし(10項)、および仮想機能なし(10.3)。
この句は、class
に基本クラスがある場合、それは集計ではないことを指定します。ここでstruct Y
はstruct X
を基本クラスとしているため、集約型ではありません。あなたは持っている特定の問題については
、標準からの次の句を取る:
8.5.4で指定された集計は、初期化子リストで初期化され
、初期化子リストの要素が取られ集約メンバーの初期化子として、下付き文字またはメンバーの順番を増やしています。各メンバーは対応するinitializer節からコピー初期化されます。 initializer-clauseが式であり、式を変換するために縮小変換(8.5.4)が必要な場合、プログラムは不正です。
あなたがX x = {0}
を行うと、集計の初期化が0
にa
を初期化するために使用されます。ただし、Y y = {0}
を実行すると、struct Y
は集約型ではないため、コンパイラは適切なコンストラクタを検索します。暗黙的に生成されたコンストラクタ(デフォルト、コピー、移動)のどれもが単一の整数で何もできないので、コンパイラはあなたのコードを拒否します。あることを
Y Y = {0};
^ ~~~
main.cpp:5:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Y &' for 1st argument
struct Y : public X {};
^
main.cpp:5:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'Y &&' for 1st argument
struct Y : public X {};
^
main.cpp:5:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
注:このコンストラクタ検索、コンパイラは実際にやろうとしているものについてもう少し明示されている++打ち鳴らすからのエラーメッセージ(online example)に関する
a proposalユースケースをサポートするための集約初期化を拡張するには、とをC++にしました。正しく読めば、期待しているセマンティクスであなたの例が有効になります。したがって、C++ 17準拠のコンパイラを待つだけです。
'clang ++ -std = C++ 1z'バージョン4.0.1がコンパイルされ、 ' g ++ -std = C++ 17'バージョン7.2.1がコンパイルされますが、 でもVisual Studio 2017 'cl'バージョン19.12.25816はまだありません –