似乎_BitScanReverse,尽管是一个内在的而不是一个真正的函数,但不能在Visual C ++中的constexpr函数中调用。我知道我可以用更慢的方式自己实现这个操作,这对于它在编译时进行评估的情况会很好,但不幸的是它不会这样做。对于在运行时进行评估的情况,它只是1个时钟周期的单CPU指令(BSR)。我还没有尝试过GCC / Clang中的__builtin_clz,但它可能会或可能不会出现同样的问题,我希望这些代码可以在主要的编译器中运行,(对于非GCC,非缓慢回退) -Clang,非VC编译器。)
思想/问题:
在编译时进行评估时,是否有一种简单的方法可以让函数使用一个代码块,这样它就可以是constexpr-safe,并且可以为运行时提供不同的代码块,这样它就可以很快? (如果是这样,这也与我的其他一些问题有关。)
或者,有没有办法欺骗编译器能够为constexpr代码评估_BitScanReverse?
附带问题:
有没有计划最终将其添加到C ++标准?他们已经添加了std :: log2和std :: ilogb,但这些都是通过浮点数而不是只做一个BSR(或者是ARM芯片上的CLZ和减法)。
答案 0 :(得分:1)
对于 C++20
,您可以使用 std::bit_width
和其他形式的 <bit>
标头
template< class T >
constexpr T bit_width(T x) noexcept;
#include <bit>
#include <bitset>
#include <iostream>
#include <array>
using BitArray = std::array<unsigned, 8>;
constexpr BitArray Bits() {
BitArray bits;
for (unsigned x{0}; x != 8; ++x)
bits[x] = std::bit_width(x);
return bits;
}
auto main() -> int {
constexpr BitArray bits = Bits();
for (unsigned x{0}; x != 8; ++x) {
std::cout
<< "bit_width( "
<< std::bitset<4>{x} << " ) = "
<< bits[x] << " "
<< std::bit_width(x) << '\n';
}
}
在 Godbolt
上试试答案 1 :(得分:1)
是否有一种简单的方法可以让函数在编译时评估时使用一个代码块,以便它可以是 constexpr 安全的,并且在运行时使用不同的代码块,以便它可以快速? (如果是这样,这也与我的其他一些问题有关。)
从 C++20 开始,是的! std::is_constant_evaluated 正是为了这个目的。
所以你现在可以:
SELECT MAX(water) FROM kn1 WHERE datetime > TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 month)) ORDER BY datetime