在聚合和POD 結構的初始化列表中省略外大括號的混亂
在C 程式設計領域,出現一個常見問題,關於在初始化清單中使用大括號。具體來說,程式設計師可能會遇到這樣的情況:某些聚合類型似乎需要外大括號,但其他聚合類型則不需要。本文旨在更深入地探討該主題,並澄清何時可以省略外大括號。
問題
在Visual C 2010 中編譯以下程式碼時,產生錯誤訊息:
struct A { int foo; double bar; }; std::array<A, 2> a1 = // error C2078: too many initializers { {0, 0.1}, {2, 3.4} }; // OK std::array<double, 2> a2 = {0.1, 2.3};
此錯誤顯示a1 的初始值定項太多,表示需要額外的大括號。但是,省略 a2 的外大括號不會導致錯誤。這種差異提出了為什麼 a1 需要外括號而不是 a2 的問題。
解釋
理解這種差異背後原因的關鍵在於std::array 的性質。 std::array 被分類為聚合和普通舊資料類型 (POD),而其他標準庫容器則不然。與具有使用者定義建構函數的容器不同,std::array 沒有。它的第一個資料成員是一個大小為 N 的數組,指定為模板參數。此資料成員使用初始化清單直接初始化。額外的大括號是必要的,因為它們包含正在初始化的內部陣列。
為了進一步說明這個概念,請考慮自訂聚合類型Aarray,定義如下:
// Custom aggregate with no user-defined constructor struct Aarray { A data[2]; // An internal array };
初始化此結構需要使用大括號來表示內部陣列的開始和結束初始化:
Aarray a1 = { { // Begins initialization of the internal array { // Initializes the first element of the internal array 0, 0.1 }, // Ends initialization of the first element {2, 3.4} // Initializes the second element of the internal array } // Ends initialization of the internal array }; // ERROR: Too many initializers if not using braces Aarray b1 = { 0, 0.1, 2, 3.4 };
Double 的情況
對於std::array
std::array<double, 2> a2 = {0.1, 2.3};
大括號用法的澄清
C 標準提供了有關以下方面的指南在初始化清單中使用大括號。 C 11 規範的第§8.5.1/11 節規定,如果初始值設定項清單以左大括號開頭,則每個後續的以逗號分隔的初始值設定項子句清單都會初始化子聚合的成員。另一方面,如果子聚合的初始值設定項清單不以左大括號開頭,則僅採用足夠的初始值設定項子句來初始化子聚合成員,而任何剩餘的初始值設定項子句則初始化下一個聚合成員。
結論
在初始化清單中使用外大括號對於聚合和 POD 結構(例如 std::array)至關重要,因為這些類型沒有使用者定義的建構函數,並且內部陣列是直接初始化的。另一方面,對於原始類型,可以省略外部大括號,因為原始值是在聚合內直接初始化的。透過了解這些情況之間的差異,程式設計師可以確保正確的初始化並避免編譯器錯誤。
以上是聚合的 C 初始值設定項目清單何時需要外括號?的詳細內容。更多資訊請關注PHP中文網其他相關文章!