考虑以下模板:
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
是否实际被实例化?
答案 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
将按预期启动。