2010-04-10 70 views

回答

4

这正好从8.5/16第一子弹8.5.4表初始化和从8.5.4/3第三子弹8.5.1集合初始化,然后8.5.1/4

与含有N A大括号内的初始列表初始化未知大小的数组初始化子句,其中应大于零,被定义为具有元素

唯一区别是如果对象是数组= { ... }{ ... }是第一个被称为复制列表初始化第二个被称为直接列表初始化,所以这两种都是列表初始化。在这两种情况下,数组的元素都是从初始化程序列表的元素中复制初始化的。

注意到有这些形式之间的微妙区别,如果数组的大小和列表是空的,在这种情况下 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做了改变。

+0

谢谢:) 有趣的(但非常微妙)关于差异btw初始化与空列表vs非空列表。我想知道对称会有更好的东西吗? – 2010-04-10 14:09:27

+0

你也知道,如果: int(&& arr)[] = {1,2,3};或者int(&& arr)[3] = {1,2,3}是否被允许? – 2010-04-10 14:10:02

+0

@Faisal,注意到'explicit A(int = 0);'是一个显式的默认构造函数。所以这种改变可能会影响比人们首先想到的更多的节目。但我认为FCD的行为更有利,因为“显式”并没有真正说出有关默认构造的内容,而更多地是关于参数转换:) – 2010-04-10 14:12:24

0

是的,它是有效的,并且已经有数十年了,甚至在C中。尺寸仅仅设置为提供的元件的数量。不幸的是,我不知道这个参考。

(附加奖励...)如果您需要的元素数使用sizeof(x)/sizeof(*x)。如果您添加或删除条目,那么编写一个可能变得无效的常量会更安全。

编辑:正如在评论中指出的,有问题的代码缺少=(我错过了一个事实),没有它,它在任何当前的C或C++标准中都是无效的。

+5

错了。没有=符号,它只在C++ 0x(不在C++ 03中)有效。 – SoapBox 2010-04-10 13:53:23