std::bitset 是编译期定长的位容器,适用于位图索引、状态标记等场景,但不支持运行时动态大小和直接进制转换;使用时需注意越界未定义行为、隐式截断及无符号性限制。

直接说结论: std::bitset 是 C++ 标准库中用于编译期确定大小的位容器,适合做位图索引、状态标记、紧凑布尔数组;但它不支持运行时动态大小,也不能直接用于进制转换——进制转换得靠手动位运算或 std::stoi/std::bitset::to_string() 配合字符串处理。
bitset 用作位图索引:固定大小 + 快速查改
位图索引本质是用每个 bit 表示一个元素是否存在(0/1)。std::bitset 天然适配,前提是索引范围已知且静态(比如 0~999 的 ID 映射)。
- 声明时必须指定模板参数 N:
std::bitset bitmap;,N 是编译期常量 - 设置第 i 位:
bitmap.set(i);(i 从 0 开始,越界不检查,行为未定义) - 查询第 i 位:
bitmap.test(i)或bitmap[i](后者返回std::bitset::reference,可读可写) - 清空所有位:
bitmap.reset();翻转所有位:bitmap.flip() - 注意:不支持迭代器遍历,想枚举置位位置需手动循环
for (size_t i = 0; i
bitset 与二进制字符串互转:to_string() 和构造函数
std::bitset 本身不是进制转换工具,但能作为二进制字符串和整数之间的“中转站”。
- 从二进制字符串构造:
std::bitset b("10101010");—— 字符串必须只含 '0'/'1',长度不能超模板大小,否则编译失败 - 转为二进制字符串:
b.to_string()返回std::string,高位在前(如bitset(5).to_string()→"0101") - 想转成十进制整数?
b.to_ulong()或b.to_ullong()(溢出抛std::overflow_error) - 反向转换(int → bitset)只能通过字符串中转,或逐位赋值:
std::bitset b; for (int i = 0; i > i) & 1;
常见踩坑点:越界、隐式截断、无符号性
用 std::bitset 最容易忽略底层无符号性和尺寸约束。
立即学习“C++免费学习笔记(深入)”;
- 越界访问
bitset[N]不触发异常,而是未定义行为(尤其test(N)中 N == N 会 crash 或返回随机值) - 用
to_ulong()转大 bitset(如bitset)可能溢出 —— 改用to_ullong(),但超过 64 位仍不行 - 构造时传入整数:
std::bitset(255)没问题,但std::bitset(256)会静默截断为 0(因为只取低 8 位) - 没有
push_back或 resize —— 真需要动态大小,请换std::vector<bool></bool>(注意它不是标准容器)或boost::dynamic_bitset
真正难的不是语法,是设计时就想清楚:这个位图最大可能有多大?是否要跨平台序列化?是否要频繁扫描置位?这些决定了你该用 bitset、vector<bool></bool> 还是手写 uint64_t 数组。别等跑出奇怪的 test(i) 返回 true 才去查 i 是否越界。










