我有这个函数用于零覆盖事物,它使用 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 overwriten");
const size_t size = sizeof(generic);
unsigned char *variableData = (unsigned char*)(variableAddress);
for (size_t i = 0; i < size; i++)
variableData[i] = 0;
}
我在这里称之为:
int main()
{
being *creature = new being(100, "a guinea pig"); // being is not a POD type
overwriteWithZeros<false>(creature);
// totally unrelated stuff...
}
并且由于 safeMode
是一个编译时值,我不知道为什么它是真的还是假的,static_assert 总是“发生”,给我当时预期的错误 being
不是 POD 类型,就好像 static_assert 之前的 if
根本不存在一样。
那么,我做错了什么?
既然你证实了我的怀疑(if
本身是在运行时评估的,尽管 safeMode
是否是编译时值,而 static_assert
在编译时评估),我将主要问题更改为:
我可以做些什么来实现我在这里尝试的目标?
最佳答案
问题是 static_assert
在编译时计算,这意味着当编译器找到它时,它会计算它,而不管它在哪里(除非它被像 #ifdef
这样的宏排除)。要解决此问题,您应该使启用标志成为评估本身的一部分:
static_assert(!safeMode || std::is_pod<generic>::value, "Only POD types can be properly overwriten");
这是允许的,因为 safeMode
是编译时值(作为模板参数)。
在这两种情况下,static_assert
将被评估,但使用 safeMode == false
它总是评估为 true
.
关于c++ - 如何为 static_assert 的评估设置前提条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33453738/