帶有非類型模板參數的靜態斷言
在 C 中,static_assert 用於在編譯時檢查條件。然而,不同的編譯器在使用具有非類型模板參數的 static_assert 時表現出不同的行為。
問題:
以下程式碼片段:
<code class="cpp">template <int answer> struct Hitchhiker { static_assert(sizeof(answer) != sizeof(answer), "Invalid answer"); }; template <> struct Hitchhiker<42> {};</code>
使用 GCC 和 Clang 編譯時會產生不同的結果。在GCC中,只有在實例化Hitchhiker時參數不是42時才會產生斷言錯誤。在Clang中,即使沒有實例化範本也會產生斷言錯誤。
修改斷言如下:
<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),沒有有效專業化的未實例化模板被認為是格式錯誤的,不需要進行診斷。
結論:
在對於原始程式碼,GCC 選擇不對未實例化的範本發出診斷。另一方面,Clang 決定發出診斷訊息,儘管標準並沒有要求這樣做。修改後的程式碼的行為在編譯器之間更加一致,因為僅在實際實例化模板時才檢查斷言。
需要注意的是,在這種情況下診斷的存在或不存在並不表示錯誤在代碼中。未實例化的模板本質上是格式錯誤的,任何嘗試使用無效的專業化來實例化它都會導致編譯錯誤。
以上是為什麼帶有非型別模板參數的「static_assert」在 GCC 和 Clang 中表現不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!