gpt4 book ai didi

c++ - 带有条件 constexpr 被调用者的 constexpr 函数

转载 作者:搜寻专家 更新时间:2023-10-31 02:02:14 24 4
gpt4 key购买 nike

示例代码:

#include <cstdint>

//#define USE_CONSTEXPR_INTRINSICS

#if defined (USE_CONSTEXPR_INTRINSICS)
namespace intrin
{
[[nodiscard]] constexpr int lsb(std::uint64_t value)
{
int r = 0;
while (value <<= 1) ++r;
return 63 - r;
}
}
#else
namespace intrin
{
[[nodiscard]] inline int lsb(std::uint64_t value)
{
return __builtin_ctzll(value);
}
}
#endif

constexpr int f(std::uint64_t v)
{
return intrin::lsb(v);
}

#if defined (USE_CONSTEXPR_INTRINSICS)
static_assert(f(13) == 3);
#endif

int main() {}

有一个“内部”函数 lsb,我可以有条件地将其编译为 constexpr - 以允许使用 static_assert 进行静态测试(这也是有条件编译的,与 constexpr 内部函数相同)。问题来自于 f 被标记为 constexpr 的事实——这使得当 lsb 不是 constexpr 时它的格式不正确。目前我通过

来“解决”这个问题
#if defined (USE_CONSTEXPR_INTRINSICS)
#define INTRIN_CONSTEXPR constexpr
#else
#define INTRIN_CONSTEXPR inline
#endif

然后将f声明为

INTRIN_CONSTEXPR int f(std::uint64_t v)

但对我来说这个解决方案并不理想,因为有很多函数使用 lsb,有时非常间接,而且它变得很难跟踪(不需要诊断,所以有时它因编译器而异) 和不合适的地方。我更喜欢的是只在需要时进行检查——比如围绕 static_assert——否则编译器保持沉默。

目前有什么方法可以让它更自动化吗?有希望以后会更容易吗?

最佳答案

C++20 使用 std::is_constant_evaluated 使这变得微不足道

[[nodiscard]] constexpr int lsb(std::uint64_t value)
{
if (std::is_constant_evaluated())
{
int r = 0;
while (value <<= 1) ++r;
return 63 - r;
}
else
{
return __builtin_ctzll(value);
}
}

在 constexpr 上下文中:

static_assert(lsb(1) == 0); // OK

在运行时上下文中:

auto test(int n)
{
return lsb(n);
}

编译为:

test(int):
movsx rax, edi
rep bsf rax, rax
ret

请注意它不是 if constexpr(std::is_constant_evaluated())。这将始终返回 true


对于任何看到这里的人来说,为了简洁起见,alg 是不完整的,lsb(0) 应该返回 64

关于c++ - 带有条件 constexpr 被调用者的 constexpr 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57672044/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com