数组成员是否可以自引用初始化
Can array members be initialized self-referentially?
考虑以下代码,其中我们基于D
的另一部分初始化D
的一部分:
struct c {
c() : D{rand(), D[0]} {}
int D[2];
};
int main() {
c C;
assert(C.D[0] == C.D[1]);
}
上述程序是否定义明确?我们可以安全地使用同一数组的一部分来初始化它的另一部分吗?
当聚合(包括数组(从大括号列表初始化时,每个聚合元素都从列表的相应元素初始化("按下标或成员顺序递增"(。尽管我找不到一个确切的规则来说明每个元素初始化都是在前一个元素初始化之后排序的,但标准中有一个例子清楚地暗示这是预期的含义。示例在 [dcl.init.aggr] 中:
struct S { int a; const char* b; int c; int d = b[a]; }; S ss = { 1, "asdf" };
用
1
初始化ss.a
,用"asdf"
ss.b
初始化,ss.c
用形式int{}
(即0
(的表达式的值初始化,用ss.b[ss.a]
的值(即’s’
(初始化ss.d
数组成员可以自引用初始化吗?
是的。
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.
};
根据 cppreference.com:
聚合初始化的效果包括:
每个数组元素或非静态类成员,按数组顺序排列 类定义中的下标/外观,从 初始值设定项列表的相应子句。
您的代码似乎很好。然而,这在某种程度上令人困惑。
写
D{rand(),D[0]}
不是一个好习惯,因为当 构造函数将运行,第一个 rand(( 不一定是 然后执行 D[0],这完全取决于编译器,D[0] 可能是 首先执行,在这种情况下 d[1] 将包含垃圾值。它 完全取决于编译器,它可以编译第二个参数 首先是第一个参数,反之亦然,执行此参数 语句可能会导致未知行为。
- C++-模板嵌套类的引用初始化无效
- 在引用初始化中使用已删除的复制构造函数进行复制初始化
- 模板流运算符重载错误:引用初始化无效,与basic_istream和basic_ifstream之间的差异有关
- 具有字符串文本构造函数的类不适用于 const 引用初始化
- 自定义初始化数组与 std::make_unique
- 类型为"短整型 (&)"的引用初始化无效
- 引用初始化和常量表达式
- C++具有自定义初始化的静态调度
- 在Visual Studio 2013中为rvalue引用初始化捕获
- 从大括号括起来的初始值设定项列表进行的Lvalue引用初始化无法编译
- Visual C++ 2015 中右值的非常量引用初始化无效
- 是否可以使用对派生类实例的基类引用初始化派生类引用
- 类型'int&'的引用初始化无效,传递参数 1 时出错
- 引用初始化表单
- 从类型为"int*"的临时引用初始化类型为"int&"的非常量引用无效
- 简单的C++日志记录类-ostream引用初始化
- 错误:类型为"cv::Mat&"的非常量引用初始化无效
- 为什么我收到类型为"const vec&"的引用初始化无效
- 从类型为"char*"的临时引用初始化类型为"char*&"的非常量引用
- 数组成员是否可以自引用初始化