std::bitset 是编译期确定大小的位序列容器,非动态内存分配,适用于状态压缩、标志位管理等;支持整数/字符串初始化、下标访问、位运算及置位/清位/翻转操作。

std::bitset 是 C++ 标准库中用于**编译期确定大小的位序列容器**,它不是动态分配内存的 STL 容器(不满足 Allocator 要求),但用法简洁、性能极高,特别适合做**状态压缩、标志位管理、布尔数组优化**等场景。
基本用法:定义、初始化与访问
bitset 的大小必须是编译期常量(模板参数),不能运行时传入。常见初始化方式:
-
全零初始化:
std::bitset flags;→ 全为 0 -
从整数初始化:
std::bitset b(42);→ 二进制 00101010(低位在右) -
从字符串初始化:
std::bitset s("101100");→ 右对齐填充前导 0,结果为 00101100 -
下标访问:
b[3]返回引用,可读可写(支持b[3] = true;) -
安全取值:
b.test(3)返回 bool,越界会抛std::out_of_range
常用操作:位运算与状态切换
bitset 重载了全部位运算符,支持链式操作,语义清晰:
-
置位/清位/翻转:
b.set(2);(第 2 位设为 1)、b.reset(2);(设为 0)、b.flip(2);(翻转);无参数时操作全部位 -
位运算:
a & b(与)、a | b(或)、a ^ b(异或)、~a(取反)——返回新 bitset,原对象不变 -
移位:
b 左移两位(高位丢弃,低位补 0),b >> 1同理;原地移位用b -
判断状态:
b.any()(是否有 1)、b.none()(是否全 0)、b.all()(C++11 起,是否全 1)
实用技巧:转换、计数与状态压缩示例
实际开发中常需与其他类型互转,或利用 bitset 压缩多状态:
立即学习“C++免费学习笔记(深入)”;
-
转整数:
b.to_ulong()(适合 ≤ 32 位)、b.to_ullong()(≤ 64 位),溢出抛异常;b.to_string()得到 "00101100" -
统计 1 的个数:
b.count()—— 编译器通常优化为 popcnt 指令,O(1) 时间 -
状态压缩典型用法:比如表示一个 12 人的小组出席状态,用
bitset仅占 2 字节,比 vector更紧凑、更快速;枚举子集也可结合位运算: for (int mask = 0; mask b(mask); ... }
注意事项与替代方案
bitset 强大但有边界,用前需确认是否适用:
- 大小必须编译期已知,无法像
vector那样动态伸缩 - 不支持迭代器(无 begin()/end()),如需遍历建议用循环索引 +
test() - 若需运行时大小,考虑
std::vector(空间优化特化)或boost::dynamic_bitset - 高频单点访问且 size 小 → bitset 最优;频繁插入删除或 size 极大 → 考虑其他结构
基本上就这些。掌握 bitset 的核心是理解它“静态+位级+值语义”的定位——不是万能容器,但在状态标记、组合枚举、集合运算等场景里,又快又稳又干净。








