2013-07-03 100 views
5

如果所有的類/結構數據成員都缺少初始值設定項,則可以使用統一的初始化語法來構造該對象。爲什麼非靜態數據成員初始值設定項會破壞統一的初始化語法?

struct foo 
{ 
    int i; 
    float f; 
}; 
... 
foo bar{ 5, 3.141f }; 

但是,如果一個或多個成員具有初始值設定項,則統一的初始化語法將變爲無效。

struct foo 
{ 
    int i; 
    float f = 0; 
}; 
... 
foo bar{ 5, 3.141f }; // Compiler error. 

我推測,除了數據成員初始化的自動實現一個或多個默認的構造函數和抑制initialization_list構造函數的默認實現。這是預期的標準嗎?它爲什麼這樣工作?

+8

沒有「initializer_list'構造函數的默認實現」。你在第一個片段中有什麼叫*聚合初始化*。 – Xeo

+1

要補充@ Xeo的評論,請參閱* 8.5.1 [dcl.init.aggr] *和* 8.5.4 [dcl.init.list] *。 – syam

+1

相關:http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821 –

回答

1

是的,這是由標準打算。你在這裏嘗試的是聚合初始化。不幸的是,由於f的初始化方法相同,您的第二個foo不再被視爲聚合。見8.5.1 [dcl.init.aggr](重點煤礦):

聚集是沒有用戶提供的構造(12.1),無brace-陣列或類(第9節) (9.2),沒有私有或受保護的非靜態數據成員(第11章),沒有基類(第10章),也沒有虛擬函數(10.3)。

因爲你必須爲會員f平等的初始化,您將需要提供自定義構造函數來支持你之後的語法:

struct foo 
{ 
    int i; 
    float f = 0; 
    constexpr foo(int i, float f) : i(i), f(f) { } 
}; 
... 
foo bar{ 5, 3.141f }; // now okay 

至於爲什麼這在指定標準,我不知道。

+1

請注意,它正在考慮下一個標準甚至允許使用非靜態數據成員初始值設定項來聚合init。 – Xeo