2013-07-29 112 views
52

考慮:奇怪的行爲[第1部分]

struct box 
{ 
    int array[3]; 
}; 

int main() 
{ 
    box a = {1}; 
} 

如果在C++以上的作品,那麼爲什麼不下面的工作?

struct box 
{ 
    int simple_int; 
}; 

int main() 
{ 
    box b = 2; 
} 

是什麼原因?

回答

84

得當,前者將使用box a = { { 1 } },讓你有一個大括號每個骨料。外面的一組大括號用於結構,內層用於數組。但是,該語言允許您省略內括號。

在後者中,沒有內省括號可以省略。你不允許省略外括號;您必須至少有一組花括號來區分彙總的初始化器列表。從某種意義上說,大括號中的「這裏列出了要彙總的內容」。當你編寫box b = 2時,編譯器不知道你想把2放在的聚合內。相反,它看起來像你試圖初始化b對象(而不是它的一部分)到2。因此,編譯器會嘗試查找將2更改爲box的構造函數或轉換。當這失敗時,你會得到一個錯誤。

+5

即使我們被允許聲明爲int:int i = {10};' –

+7

@GrijeshChauhan:我省略了它,因爲它不相關並且使討論複雜化。問題是爲什麼我們不能省略大括號,爲什麼我們可以添加它們。語言規範分別對待標量是特殊情況,而不是聚合規則的一部分。 –

+2

謝謝Grijesh,我不知道! –

17

它不起作用,因爲你的語法錯了。如果這是你想要的,你可以用一個隱含的構造函數添加對b = 2的支持。

box b = {2}; // correct syntax with no constructor 

或者

struct box 
{ 
    // implicit constructor 
    box(int i) : i(i) {} 
    int i; 
}; 

box b(2); 
box c = 2; 

或者

struct box 
{ 
    explicit box(int i) : i(i) {} 
    int i; 
}; 

box b(2); 
box c = 2; // disallowed 
+0

與'char * s =「A」'和'char * s = {「A」}類似的退出是可能的。 –

+1

@GrijeshChauhan:實際上'char * s =「A」'在C++ 11中是不可能的(無警告)。你必須使用'const'。 (好'char *'爲字符串文字是**棄用**,迂腐) – Nawaz

+1

@Nawaz有趣,所以我必須做:'const char * s = {「A」}或'const char * s =「A」'in C++ 11 **?** –