clang++
永不允許default initialization of a const variable of class-type without a user-defined constructor; g++
稍有限制(見下文)。根據this answer,這是因爲POD類型「未默認初始化」。如果我理解正確,這意味着默認初始化不會調用默認構造函數,也不會調用值初始化,因此POD類型內的數據成員不會被初始化。當然,它有一個const POD類型的未初始化值是沒有意義的,因爲它們可以初始化從不,因此不安全使用。何時以及如何默認初始化常量變量?
有這種情況的幾個變種:
- 類型在技術上是「POD」,但不包含數據成員(僅適用於函數)。使用
{}
(clang++
不認爲這是一次特殊的情況下,也沒有,我覺得,做標準,但g++
確實允許的話,即使在構造標記explicit
。) - 一個空的構造函數定義。 (這是
clang
頁面上描述問題的推薦解決方法。) - 默認構造函數聲明爲
=default
。 (C++ 11以後;類型仍然被認爲是POD,所以編譯器和標準都沒有把它當作一種特殊情況) - 使用
{}
明確調用了聚合初始化,如果我理解正確的話,它會變成值初始化。 (C++ 11起;兩種編譯器,而且我認爲,標準允許這種)
在第一種情況下,不可能有初始化成員,因此目前還不清楚爲什麼的任何實例類本身將被視爲「未初始化」,無論它是否爲const
。由於g++
允許這種行爲,使用安全嗎?爲什麼它被clang++
和標準禁止? (以及是否有任何其他情況下,g++
允許POD默認初始化其中clang++
不?)
在第二和第三種情況下,使用{}
代替=default
似乎很奇怪,我的要求。 編輯:this question很好地解釋了這種差異,所以我刪除了問題中關於區別的部分。 (我仍然認爲這是語言的一個非常令人困惑的方面,雖然)。
最後,將Foo f{}
總是零初始化的內置類型,如果是Foo::Foo(void)
{}
,=default
,或隱式聲明的成員?
是否有沒有成員變量的const POD類型的用例?你可以使用非const類型的函數,因爲沒有可能被錯誤修改的成員。 –
@MattMcNabb我不確定。這是一種在同事的代碼中,模板工廠函數(或類似的東西)中重複出現的模式。我會盡量記住明天問那位同事明天的意圖是什麼。 –
用'{}'定義的構造函數不是一個簡單的構造函數。 – 0x499602D2