22

考虑以下代码,其中我们D根据 的另一部分来初始化 的一部分D

struct c {
    c() : D{rand(), D[0]} {}
    int D[2];
};

int main() {
    c C;
    assert(C.D[0] == C.D[1]);
}

上述程序是否定义明确?我们可以安全地使用同一个数组的一部分来初始化它的另一部分吗?

4

4 回答 4

16
于 2015-06-27T18:01:40.307 回答
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).
};

这里 in 的第一个元素a将是 in 的任何值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.
};
于 2015-06-27T23:14:58.640 回答
2

根据cppreference.com

聚合初始化的效果是:

每个数组元素或非静态类成员,按照类定义中数组下标/外观的顺序,从初始化列表的相应子句复制初始化。

你的代码看起来不错。然而不知何故令人困惑。

于 2015-06-27T18:14:38.020 回答
0

编写 不是一个好习惯D{rand(),D[0]},因为当构造函数运行时,不必先执行 rand() 然后执行 D[0],这完全取决于编译器,可以先执行 D[0],在这种情况 d[1] 将包含垃圾值。它完全取决于编译器,它可以先编译第二个参数,然后再编译第一个参数,反之亦然,执行此语句可能会导致未知行为。

于 2015-06-27T18:06:19.530 回答