3

この構造を持つ:

struct A {
    struct B {
        int a = 21;
        int b;
        int c = 22;
        int d;
        int e = 23;
    };
    B b1  = { 11, 12 };
    B b2  = { 11, 12, 13 };
    int x;
};

そして次のように宣言します。

A a = { { 1, 2, 3, 4 }, { 1 }, 5 };

Clang (3.8.0) と GCC (5.4.0) の両方によると、これらは 8 つの可能な組み合わせの値です (a.b1.e と a.b2.a は繰り返されるケースです)。から(またはそうでない)、:

a.b1.a = 1   // 111
a.b1.b = 2   // 110
a.b1.c = 3   // 101
a.b1.d = 4   // 100
a.b2.b = 0   // 010    // Why not 12 instead of  0? -> Explained in N3605
a.b2.c = 22  // 011    // Why not  0 instead of 22 ?  Why not 13 ?
a.b2.d = 0   // 000
a.b2.e = 23  // 001    // Why not  0 instead of 23 ?

N3605および C++14 標準 (ISO/IEC 14882:2014) のセクション 8.5.1、パラグラフ 7の例を考慮に入れます。

集約内のメンバーよりもリスト内の初期化句の数が少ない場合、明示的に初期化されていない各メンバーは、brace-or-equal-initializer から初期化されるか、brace-or-equal-initializerない場合、空のイニシャライザ リスト (8.5.4) から。

ケース010が正しいと思います。では、なぜケース 011 (a.b2.c) と 001 (a.b2.e) もゼロに等しくないのでしょうか? a.b2 には「初期化子がある」ため、ケース 010 はゼロです。したがって、「非静的データ メンバー初期化子は無視されます」( N3605再び)。デフォルトのメンバー初期化子も無視されないのはなぜですか?

実際、C++14 標準の引用を読むと、ケース 010 は 12 (ゼロ) であり、ケース 011 と 001 はゼロ (実際にはそうです) であることがより理にかなっています。だから私が理解していないのは、 a.b2 が「初期化子を持つ」と見なされる場合とそうでない場合がある理由です。

4

2 に答える 2

6

aすべてのメンバーの初期化子を使用して宣言します: b1b2およびx。つまり、あたかも構築するかのように

a.b1 = B{ 1, 2, 3, 4 };
a.b2 = B{ 1 };
a.x = 5;

Bの定義は、それがB{ 1, 2, 3, 4 }意味B{ 1, 2, 3, 4, 23 }し、それがB{ 1 }意味することを示していますB{ 1, 0, 22, 0, 23 }。そして、それはまさにあなたが得る結果です。


もし書いていたら

A a = { { 1, 2, 3, 4 }, };

次にa.b2、デフォルトの { 11, 12 } を使用して初期化されます。

a.b1 = B{ 1, 2, 3, 4 };
a.b2 = B{ 11, 12 };
a.x = {};

のコンストラクターがそれらを見るずっと前に、完全に構築されたオブジェクトであるとあなたの例の{ 1 }andのようなブレース式を考えると役立つかもしれません。{ 11, 12 }BA

于 2017-01-10T17:19:31.870 に答える
2

この例{1, 2, 3, 4}では、 の初期化子ですB b1。コンパイラには既に初期化子があるため、これ以上参照し{ 11, 12 }ません。

于 2017-01-10T17:00:07.610 に答える