2010-04-10 41 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