私有建構子與聚合初始化:意外的互動
在C 中,將預設建構子宣告為私有會自然地導致人們假設關聯類型的預設建構將變得不可存取。然而,當使用大括號括起來的初始化語法時,會出現一種奇怪的行為。
考慮以下範例:
class C { C() = default; }; int main() { C c; // error: C::C() is private auto c2 = C(); // error: calling a private constructor }
意外的是,上述程式碼在所有主要編譯器上都會產生錯誤。這是預期的行為,因為預設的建構函式確實被宣告為私有。然而,使用大括號括起來的初始化突然允許預設構造:
int main() { C c{}; // OK auto c2 = C{}; // OK }
這種意外行為背後的原因在於 C 標準函式庫的複雜性。根據 C 14 標準 (8.4.2/5),如果函數是使用者聲明的並且在第一次宣告時未明確預設或刪除,則該函數被視為「使用者提供的」。
在下列情況下在上面的 C 類別中,預設建構子在其第一個宣告中明確預設。這意味著它不被視為“用戶提供的”。因此,C 類沒有使用者提供的建構函數,這使得它根據8.5.1/1 中的定義成為聚合:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
因此,C 允許使用大括號括起來的初始化類,允許默認構造,即使構造函數被宣告為私有。這種行為可能會令人驚訝,並且在某些情況下可能會導致不良後果。
以上是為什麼我可以使用私有預設建構函式初始化聚合?的詳細內容。更多資訊請關注PHP中文網其他相關文章!