考慮下面的代碼中,我們基於對D
另一部分初始化的D
部分:數組成員是否可以自我初始化?
struct c {
c() : D{rand(), D[0]} {}
int D[2];
};
int main() {
c C;
assert(C.D[0] == C.D[1]);
}
在上述程序明確定義?我們可以安全地使用同一個數組的一部分來初始化它的另一部分嗎?
考慮下面的代碼中,我們基於對D
另一部分初始化的D
部分:數組成員是否可以自我初始化?
struct c {
c() : D{rand(), D[0]} {}
int D[2];
};
int main() {
c C;
assert(C.D[0] == C.D[1]);
}
在上述程序明確定義?我們可以安全地使用同一個數組的一部分來初始化它的另一部分嗎?
數組成員是否可以自我初始化?
是。
struct c {
int a[3];
c() : a{4, a[0], 3} {} // a[0] is initialized to 4.
// a[1] is initialized to whatever a[0] is. (4)
// a[2] is initialized to 3.
};
但考慮這個例子:
struct c {
int a[3];
c() : a{a[1], 4, a[1]} {} // a[0] is initialized to whatever a[1] is.(Garbage value)
// a[1] is initialized to 4.
// a[2] is initialized to what a[1] is now (4).
};
在這裏,在a
的第一個元素將是任何值是a[1]
, 這將很可能是垃圾的價值。 第二個元素被初始化爲4
,第三個元素被初始化爲 ,現在是a[1]
,它的值是4
。
此外,當你不列出未列出的{}
, 元素中的陣列中的所有元素,將被默認初始化:
struct c {
int a[5]; // notice the size
c() : a{a[1], 2, 3, 4}{} // a[0] will get value that is in a[1]
// but since a[1] has garbage value,
// it will be default initialized to 0.
// a[1] = 2
// a[2] = 3
// a[3] = 4
// a[4] is not listed and will get 0.
};
然而,上市已經初始化的元素會給你你想要的價值。
使用上面的例子:
struct c {
int a[5];
c() : a{1, a[0], 3, 4}{} // a[0] = 1
// a[1] = 1
// a[2] = 3
// a[3] = 4
// a[4] is not listed and will get 0.
};
當聚合(包括數組)從一個支撐列表初始化時,每個聚合元素都從列表的相應元素(「增加下標或成員順序」)進行初始化。儘管我找不到一個確切的規則,說每個元素的初始化都是在前一個元素之後進行排序的,但標準中有一個例子清楚地表明這是預期的意思。該例子是在[dcl.init.aggr]:
struct S { int a; const char* b; int c; int d = b[a]; }; S ss = { 1, "asdf" };
初始化
ss.a
與1
,ss.b
與"asdf"
,ss.c
與表單int{}
(即,0
)的表達式的值,和ss.d
與ss.b[ss.a]
的值(即,’s’
)
它不是寫一個很好的做法因爲當構造函數運行時,不需要首先執行rand()將執行 然後D [0],這一切都取決於編譯器,D [0]可能是 首先執行,在這種情況下,d [ 1]將包含垃圾值。它 完全取決於編譯器,它可以先編譯第二個參數 ,然後第一個參數或反之亦然,執行此 語句可能會導致未知行爲。
我的第一個想法是「不要」。我的第二個想法是「初始化程序列出havr命令gurantees」。我的第三個想法是「初始化發生在論證評估之後,不是嗎?」 – Yakk