如何为 static_assert 的评估设置前置条件?

How to set a pre-condition to the evaluation of a static_assert?

我有这个零覆盖函数,它使用 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 总是 "happens",给我然后 being 不是 POD 类型的预期错误,就好像 static_assert 之前的 if 根本不存在一样。

那么,我做错了什么?

因为你证实了我的怀疑(if 本身在 运行 时求值,尽管 safeMode 是否是编译时值,而 static_assert 在编译时间),我将主要问题更改为:

我可以做些什么来实现我在这里尝试的目标?

static_assert 的意思就是,断言是在编译时静态完成的。

问题是 static_assert 是在编译时计算的,这意味着当编译器找到它时,它会计算它,而不管它在哪里(除非它被 [=12 这样的宏排除) =]).要解决此问题,您应该将启用标志作为评估本身的一部分:

static_assert(!safeMode || std::is_pod<generic>::value, "Only POD types can be properly overwriten");

这是允许的,因为 safeMode 是编译时值(作为模板参数)。

在这两种情况下,static_assert 都将被计算,但对于 safeMode == false,它将始终计算为 true