在constexpr函数中有效调用_BitScanReverse或__builtin_clz的方法?

Nei*_*son 7 c++ g++ intrinsics visual-c++ constexpr

似乎_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和减法).

Sur*_*urt 2

您可以C++20使用std::bit_width和其他表单<bit>标题

template< class T >
constexpr T bit_width(T x) noexcept;
Run Code Online (Sandbox Code Playgroud)
#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';
    }
}
Run Code Online (Sandbox Code Playgroud)

在Godbolt上尝试一下