[英]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
帶初始值設定項: b1
, b2
和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 = {};
在A
的構造函數甚至看到它們之前很久,將示例中的{ 1 }
和{ 11, 12 }
{ 1 }
這些大括號表達式視為完全構造的B
對象可能會有所幫助。
在該示例中, {1, 2, 3, 4}
是B b1
的初始化器。 編譯器已經有一個初始化器,所以現在它不再看{ 11, 12 }
了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.