在C++ 11中,模板中static_assert的操作是否应该取决于该模板是否已经实例化?例如,使用以下代码
template <int I>
void sa() { static_assert(0,"Hello."); }
int main(int argc, char *argv[]) { return 0; }
Run Code Online (Sandbox Code Playgroud)
GCC 4.5.0将无法断言,并生成"Hello".信息.另一方面,Digital Mars Compiler版本8.42n没有给出任何消息.
Joh*_*itb 50
GCC是正确的,其他编译器也是正确的.请参阅规格中的14.6p8
如果无法为模板定义生成有效的专业化,并且未实例化该模板,则模板定义不正确,无需诊断.
因此,编译器可以自由拒绝以下内容
template<typename T>
void f() {
static_assert(0, "may trigger immediately!");
static_assert(sizeof(T) == 0, "may trigger immediately!");
}
Run Code Online (Sandbox Code Playgroud)
如果你想要安全,你必须安排它,以便编译器在实例化之前无法知道布尔表达式是真还是假.例如,通过获取的价值getvalue<T>::value,有getvalue是一个类模板(一个可以专注,所以编译器不可能知道布尔值的话).
C++0x 草案 ( N3242 ) 在 14.6p8 中说:
\n\n\n\n\n“如果无法为模板定义生成\n 有效的专业化,\n 并且该模板未实例化,\n 模板定义\n 格式不正确,\n 无诊断必需的。”
\n
同样的词语也出现在C++03标准中。
\n\n对于问题中的示例,无法为此模板进行有效的实例化,因此引用的措辞适用。
\n\n由于不需要诊断,因此如果模板未实例化,则编译器可以编译程序。当然,如果实例化了该程序,则该程序格式错误,需要进行诊断。
\n我使用了一个辅助函数来使 false 依赖于模板参数:
template<typename T>
bool dependentFalse<T>()
{
return false;
}
template<typename T>
Foo foo()
{
static_assert(dependentFalse<T>(), "this template shouldn't be instantiated");
}
Run Code Online (Sandbox Code Playgroud)