这个列表初始化是一个未知大小的数组在C ++ 0x中有效吗?
int main() { int x[]{0, 1,2,3,4}; return x[0]; }
我认为这是有效的,但我会感谢一些确认。
如果有人可以引用C++0x-FCD来支持他们的案子,我们将不胜感激。
谢谢!
答案 0 :(得分:4)
这从8.5/16
第一个子弹到8.5.4
列表初始化,从8.5.4/3
第三个子弹到8.5.1
聚合初始化然后8.5.1/4
说
使用包含n个初始化子句的大括号括起初始化列表初始化的未知大小数组,其中大于零,定义为具有元素
如果对象是= { ... }
和{ ... }
之间的数组,唯一的区别是第一个被称为 copy-list-initialization ,第二个被称为直接列表初始化,因此两者都是列表初始化的种类。在两种情况下,数组的元素都是从初始化列表的元素中复制初始化的。
请注意,如果数组具有大小并且列表为空,则这些表单之间存在细微差别,在这种情况下 8.5.4
第二个项目符号适用:
struct A {
explicit A();
};
A a[1]{}; // OK: explicit constructor can be used by direct initialization
A a[1] = {}; // ill-formed: copy initialization cannot use explicit constructor
此差异不适用于具有内容的列表,在这种情况下,第三个项目符号再次适用,但
struct A {
explicit A(int);
};
A a[1]{0}; // ill-formed: elements are copy initialized by 8.5.1
A a[1] = {0}; // ill-formed: same.
与前一个草案相比,FCD改变了这一点,现在使用空的初始化列表进行初始化总是能够使用显式默认构造函数。这是因为FCD声明元素是值初始化的,并且值初始化不关心显式性,因为它不对默认构造函数执行重载解析(它无论如何都无法找出更好或更差的匹配)。前一个草案对构造函数使用了正常的重载决策,因此在复制初始化期间拒绝了显式默认构造函数。 This defect report做了那个改变。
答案 1 :(得分:0)
是的,它是有效的,并且已经持续了数十年,甚至在C中。大小只是设置为提供的元素数量。不幸的是,我不知道这个参考文献。
(已添加奖励......)如果您需要元素数量,请使用sizeof(x)/sizeof(*x)
。如果你添加或删除条目,它比硬编码一个可能变得无效的常量更安全。
编辑:正如评论中所指出的,有问题的代码缺少=
(我错过了这个事实),没有它,它在任何当前的C或C ++标准中都无效。