在模板程式設計中,可以使用靜態斷言在編譯時強制執行某些條件。然而,不同的編譯器在評估這些斷言時可能會表現出不同的行為,正如最近的觀察所證明的那樣。
考慮以下程式碼片段:
<code class="cpp">template <int answer> struct Hitchhiker { static_assert(sizeof(answer) != sizeof(answer), "Invalid answer"); }; template <> struct Hitchhiker<42> {};</code>
在此範例中,我們嘗試使用靜態斷言來停用 Hitchhiker 的通用模板實例化。然而,在編譯時,我們注意到,即使模板未實例化,clang 也會產生斷言錯誤,而 gcc 僅在使用 42 以外的參數實例化 Hitchhiker 時才會產生錯誤。
進一步調查表明,這種差異源於此來自以下程式碼段:
<code class="cpp">template <int answer> struct Hitchhiker { static_assert(sizeof(int[answer]) != sizeof(int[answer]), "Invalid answer"); }; template <> struct Hitchhiker<42> {};</code>
使用此修改後的程式碼進行編譯時,兩個編譯器都表現出相同的行為:僅當通用模板實例化時才會觸發斷言。此行為符合C 標準,如[temp.res]/8 所指定:
If no valid specialization can be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic required.
根據此段落,如果無法為模板產生有效的專業化並且未實例化,則該模板被認為是格式錯誤的,不需要診斷。在這種情況下,clang 選擇提供診斷,而 gcc 則不提供。
要強制執行僅允許 42 個的限制,一種方法是避免定義通用模板:
<code class="cpp">template <> struct Hitchhiker<42> {};</code>
以上是為什麼 GCC 和 Clang 在未實例化模板的靜態斷言行為上有所不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!