考虑下面的代码中,我们基于对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