C++ 如何为静态断言的评估设置前提条件?
我有一个零覆盖功能,它使用静态断言检查给定对象的类型是否为POD类型:C++ 如何为静态断言的评估设置前提条件?,c++,templates,static-assert,C++,Templates,Static Assert,我有一个零覆盖功能,它使用静态断言检查给定对象的类型是否为POD类型: template <bool safeMode = true, typename generic> void overwriteWithZeros( generic *variableAddress ) { if (safeMode) static_assert(std::is_pod<generic>::value, "Only POD types can be properly overw
template <bool safeMode = true, typename generic>
void overwriteWithZeros( generic *variableAddress )
{
if (safeMode) static_assert(std::is_pod<generic>::value, "Only POD types can be properly overwriten");
const size_t size = sizeof(generic);
unsigned char *variableData = (unsigned char*)(variableAddress);
for (size_t i = 0; i < size; i++)
variableData[i] = 0;
}
模板
无效覆盖零(通用*variableAddress)
{
如果(safeMode)静态_断言(std::is_pod::value,“只能正确覆盖pod类型”);
const size\u t size=sizeof(通用);
无符号字符*变量数据=(无符号字符*)(变量地址);
对于(大小i=0;i
我在这里称之为:
int main()
{
being *creature = new being(100, "a guinea pig"); // being is not a POD type
overwriteWithZeros<false>(creature);
// totally unrelated stuff...
}
intmain()
{
being*生物=新生物(100,“豚鼠”);//生物不是豆荚类型
覆盖零(生物);
//完全无关的东西。。。
}
由于safeMode
是一个编译时值,我不知道为什么它是真的还是假的,静态断言总是“发生”,这给了我一个不是POD类型的预期错误,好像在静态断言之前这个if
根本不存在
那么,我做错了什么
由于您确认了我的怀疑(如果
本身在运行时进行评估,尽管安全模式
是否为编译时值,而静态断言
在编译时进行评估),我将主要问题改为:
我能做些什么来实现我在这里尝试的目标呢?静态断言
就是说,断言是在编译时静态完成的。问题是静态断言
是在编译时计算的,这意味着当编译器找到它时,它会对它进行计算,不管它在哪里(除非它被像#ifdef
这样的宏排除)。要解决此问题,您应使启用标志成为评估本身的一部分:
static_assert(!safeMode || std::is_pod<generic>::value, "Only POD types can be properly overwriten");
static_assert(!safeMode | | std::is_pod::value,“只能正确覆盖pod类型”);
这是允许的,因为safeMode
是编译时值(作为模板参数)
在这两种情况下,static\u assert
都将被评估,但如果safeMode==false
它将始终评估为true
,因为if
在运行时评估,而static\u assert
在编译时评估。“我能做些什么来实现我在这里尝试的目标?”-static\u assert
不需要任何费用。删除safeMode
参数并无条件保留断言。我可以这样做,但我想要一个开关来启用类型的安全检查,这样如果您真的想覆盖非POD的内容,您就可以这样做并承担后果。我想正是因为safeMode是一个编译时值,我想做的可能会奏效。。。因此,当它没有这样做时,我对可能做的事情感到困惑……编译时常量这一事实并没有改变if语句的语义。唯一的区别是当优化分支时,if(false)
将从生成的代码中消失。但这发生在编译之后,并且在任何情况下,static\u assert
都不会发出任何代码。