簡體   English   中英

C ++中的聚合成員初始化14

[英]Aggregate Member Initialization in C++14

有這個結構:

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段:

如果列表中的initializer-clause少於聚合中的成員,那么未明確初始化的每個成員都應從其brace-or-equal-initializer初始化,或者,如果沒有brace-or-equal-initializer ,從空的初始化列表(8.5.4)。

我假設案例010是正確的。 那么,為什么情況011(a.b2.c)和001(a.b2.e)也不等於零? 情況010為零,因為a.b2“確實具有初始化器”,因此“忽略非靜態數據成員初始化器”(再次為N3605 )。 為什么不忽略默認成員初始值設定項?

事實上,閱讀C ++ 14標准引用它對我來說更有意義的情況是010將是12(它是零)並且情況011和001將是零(實際上是它們)。 所以我不明白為什么a.b2有時被認為是“有一個初始化器”,有時則不是。

您為其所有成員聲明a帶初始值設定項: b1b2x 這意味着我們就好像構建一樣

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 = {};

A的構造函數甚至看到它們之前很久,將示例中的{ 1 }{ 11, 12 } { 1 }這些大括號表達式視為完全構造的B對象可能會有所幫助。

在該示例中, {1, 2, 3, 4}B b1的初始化器。 編譯器已經有一個初始化器,所以現在它不再看{ 11, 12 }了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM