std::has_single_bit 是 c++20 引入的 constexpr 函数,用于判断无符号整数二进制表示是否恰好只有一个 bit 为 1(即 2 的幂),需包含 头文件并启用 c++20,推荐使用 unsigned 类型以避免未定义行为。

std::has_single_bit 是 C++20 新增的 constexpr 工具函数
它直接告诉你一个整数的二进制表示里是否**恰好只有一个 bit 为 1**,也就是数学意义上的正整数 2 的幂(1、2、4、8、16…)。它不处理负数或零——std::has_single_bit(0) 返回 false,std::has_single_bit(-4) 编译失败(因为要求无符号或非负有符号整型,且通常只对 unsigned 类型行为明确)。
关键点:它比手写 (x & (x - 1)) == 0 && x != 0 更安全、更语义清晰,且编译器能更好优化。
必须包含 <bit></bit> 头文件并启用 C++20
很多初试者卡在这步——忘了加头文件,或者编译器没开 C++20。g++/clang++ 需要显式加 -std=c++20;MSVC 在 VS2019 16.10+ 默认支持,但项目设置里也要确认 C++ 语言标准设为 C++20。
-
#include <bit></bit>缺一不可,<cmath></cmath>或<algorithm></algorithm>都不行 - 参数类型推荐用
unsigned int、uint64_t等无符号类型,避免有符号负值引发未定义行为 - 对
int类型传入负数时,行为由实现定义,不建议依赖
常见误用:混淆 2 的幂和“2 的整数次幂”边界
std::has_single_bit 只认位模式,不关心数学意义。这意味着:
-
std::has_single_bit(1)→true(1是2^0,合法) -
std::has_single_bit(0)→false(零没有 bit 为 1) -
std::has_single_bit(0x80000000U)→true(32 位系统下,最高位为 1,仍是单个 bit) - 但若你用的是
int且该值在平台上有符号,0x80000000可能是负数,此时调用未定义
所以实际使用中,优先转成无符号类型再判: std::has_single_bit(static_cast<unsigned>(x))</unsigned>。
性能与编译期常量性
它是 constexpr 函数,所有参数为字面量时,结果在编译期就确定。比如:
static_assert(std::has_single_bit(16)); // OK static_assert(std::has_single_bit(15)); // 编译失败
运行时调用也极轻量——现代编译器(GCC 12+、Clang 14+)会将其编译为一条 test + 条件跳转,或内联为 popcnt 指令后判断是否等于 1,比手写位运算分支更稳定。
真正容易被忽略的是:它**不检查输入是否溢出或越界**,也不做范围校验。如果你从用户输入读取一个 int 再直接丢给它,而该值本应是正数但被截断为负,结果就不可靠。安全做法永远是先保证类型和符号态可控。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











