static_assert,具有实际上独立的依赖表达式

时间:2014-12-07 14:46:55

标签: c++ templates c++11 language-lawyer static-assert

考虑以下模板:

template <typename T>
void foo() {
  static_assert(sizeof(T) == 0, "Now what?");
}
  

标准(§7.4)说:

     
    

[如果static_assert的条件为false]程序格式错误,产生的诊断消息(1.4)应包括     string-literal的文本,[...]

  

(参考文献摘自https://stackoverflow.com/a/11048906/560450

实际上,static_assert在实例化函数模板foo之前不会失败,因为使用模板参数会强制编译器仅在两阶段查找期间评估条件。因此,除非实例化函数模板,否则上面的代码片段不会被视为格式错误。

另一方面,sizeof(T)> 0 + C ++ by definition。因此,条件的值实际上独立于任何模板参数!是否允许“恶意”编译器利用这一事实,并拒绝将程序视为格式错误,无论foo是否实际被实例化?

1 个答案:

答案 0 :(得分:6)

是的,允许编译器拒绝此操作,但不是必需的。

§14.6[temp.res] / p8:

  

如果无法为模板生成有效的专业化,那么   模板没有实例化,模板格式不正确,没有   需要诊断。

简单的解决方法:

template <typename T>
struct foo_protector : std::false_type {};

template <typename T>
void foo() {
  static_assert(foo_protector<T>::value, "Now what?");
}

不允许编译器拒绝foo()的定义,因为可能存在foo_protector的特化,尚未见到,因此其value成员为true 。只要您实际上没有编写这样的专业化,static_assert将按预期启动。