编译器中非类型模板参数的 static_assert 行为不一致
在 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>
当尝试使用 static_assert 禁用常规模板实例化时,Clang 和 GCC 上的行为有所不同。即使模板未实例化,Clang 也会触发断言错误,而 GCC 仅在参数值不是 42 的情况下实例化时才会引发错误。
要了解差异,让我们探索 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.
根据此规则,主模板 Hitchhiker 格式错误,因为无法生成有效的专业化。因此,不需要发出诊断。然而,尽管缺乏要求,Clang 还是选择提供诊断。
如果意图将实例化限制为仅 42 个,建议的方法是省略通用模板定义,如下所示:
<code class="cpp">template <> struct Hitchhiker<42> {};</code>
以上是为什么编译器中的“static_assert”与非类型模板参数的行为不同?的详细内容。更多信息请关注PHP中文网其他相关文章!