具有实际上独立的依赖表达式的static_assert [英] static_assert with dependent expression that is actually independent

查看:96
本文介绍了具有实际上独立的依赖表达式的static_assert的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下模板:

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

标准(第7.4节)说:

The standard (§7.4) says:

[如果对static_assert的条件为假,则该程序格式错误,并且所得到的诊断消息(1.4)应包括 字符串文字的文本,[…]

[If the condition to static_assert is false] the program is ill-formed, and the resulting diagnostic message (1.4) shall include the text of the string-literal, […]

(引用来自 https://stackoverflow.com/a/11048906/560450 )

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

In practice, the static_assert will not fail until we instantiate the function template foo, because the use othe the template parameter forces the compiler to evalute the condition only during two-phase lookup. Therefore, the code snippet above is not deemed ill-formed unless the function template is instantiated.

另一方面,在C ++中,sizeof(T)> 0 根据定义 .因此,条件的值实际上与任何模板参数无关!是否允许恶意"编译器利用这一事实,并以格式错误的形式拒绝程序,而不管是否实际实例化了foo?

On the other hand, sizeof(T) > 0 in C++ by definition. Therefore, the value of the condition is in fact independent of any template parameter! Is a "malicious" compiler allowed to take advantage of this fact, and reject the program as ill-formed, regardless whether foo is actually instantiated or not?

推荐答案

是的,允许(但不是必需)编译器拒绝该请求.

Yes, the compiler is allowed, but not required, to reject this.

§14.6[温度]/p8:

§14.6 [temp.res]/p8:

如果无法为模板生成有效的专业化,并且 模板未实例化,模板格式错误,否 需要诊断.

If no valid specialization can be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic required.

一个简单的解决方法:

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就会按预期触发.

The compiler is not allowed to reject foo()'s definition because there might be a specialization of foo_protector, not yet seen, such that its value member is true. As long as you don't actually write such a specialization, the static_assert will fire as expected.

这篇关于具有实际上独立的依赖表达式的static_assert的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆