考虑以下代码,我们根据D
的另一部分初始化部分D
:
struct c {
c() : D{rand(), D[0]} {}
int D[2];
};
int main() {
c C;
assert(C.D[0] == C.D[1]);
}
上述程序定义明确吗?我们可以安全地使用同一个数组的一部分来初始化它的另一部分吗?
答案 0 :(得分:16)
当从支撑列表初始化聚合(包括数组)时,每个聚合元素都从列表的相应元素初始化(“以增加的下标或成员顺序”)。即使我找不到一个确切的规则,即每个元素的初始化都在前一个元素之后进行排序,但标准中的一个例子清楚地表明这是预期的含义。该示例位于[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’
)
答案 1 :(得分:11)
阵列成员可以自引用初始化吗?
是
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.
};
答案 2 :(得分:2)
聚合初始化的影响是:
每个数组元素或非静态类成员,按数组顺序排列 类定义中的下标/外观是从中复制初始化的 初始化列表的相应子句。
您的代码似乎很好。 然而,某种程度上令人困惑。
答案 3 :(得分:0)
写{{1}}不是一个好习惯,因为当时。{1}} 构造函数将运行它没有必要第一个rand()将是 然后执行D [0],这一切都取决于编译器,D [0]可以 首先执行,在这种情况下,d [1]将包含垃圾值。它 完全取决于编译器,它可以编译第二个参数 首先,然后是第一个参数,反之亦然,执行此操作 声明可能会导致未知行为。