【发布时间】:2014-01-05 17:15:41
【问题描述】:
此代码在 Coliru 中编译并带有警告 [main() 中的 std::cout << 表达式中的单元化成员 a[1].i 和 a[2].i] 但在 Ideone 中正常编译。
#include <iostream>
struct A
{
int i;
A(int j) : i{j} {};
A() = default;
};
int main() {
A a[3] = { A(1) };
std::cout << a[1].i << ' ' << a[2].i << '\n';
}
根据我对 iso § 8.5 p7 的解释,Ideone 是正确的,因为本条款的第 4 个要点。
这是来自 N3797 的 §8.5 p7
对 T 类型的对象进行值初始化意味着:
- 如果 T 是(可能是 cv 限定的)类类型(第 9 条),没有默认构造函数 (12.1) 或默认构造函数是 用户提供或删除,则对象默认初始化;
- 如果 T 是一个(可能是 cv 限定的)类类型,没有用户提供或删除的默认构造函数,则该对象为零初始化 并检查默认初始化的语义约束, 如果 T 有一个重要的默认构造函数,则该对象是 默认初始化;
- 如果T是数组类型,那么每个元素都是值初始化的;
- 否则,对象被零初始化。
值初始化的对象被视为已构造并且 因此受本国际标准的规定适用于 “构造的”对象,构造函数拥有的“对象” 完成,”等等,即使没有为对象的构造函数调用 初始化。
【问题讨论】:
-
Coliru 是正确的(尽管您没有指定使用的编译器)。
-
等等,我可能错了。
-
警告因编译器而异,没有对错。
-
@chris 我的钱(不多,授予)将在 ideone 上是正确的。我希望对数组中的其他
As 进行值初始化,以初始化相应的is。 -
@juanchopanza,是的,这就是
int a[3] = {1};将a[1]和a[2]保留为 0 的全部内容,但改为使用课程,并且出于某种原因,这是您学到的一条规则在我一开始总是忘记的初学者课程中。
标签: c++ c++11 initialization language-lawyer