☰
深入理解C++ 容器 std::bitset
2026/10/26 1:54:10 网站建设 项目流程

std::bitset是 C++ 标准库中用于处理固定长度位序列的工具。你可以把它理解为一个长度在编译期就已确定的二进制数组,它既提供了类似数组的按位访问能力,又像整数一样支持整套位运算,同时还会将存储空间压缩到极致(理论上每个 bit 只占 1 bit 空间,无额外指针开销)。


核心特性速览

  • 固定大小,编译期确定:大小N是模板参数,必须在编译时是常量。一旦定义,长度不可改变。

  • 空间高效:标准要求以最紧凑的方式存储N个位,没有动态内存分配。

  • 支持完整位运算:&、|、^、~、<<、>>以及对应的复合赋值运算符&=、|=、^=、<<=、>>=全部可用。

  • 与字符串和整数互转:可以从"1010"这样的字符串或整数构造,也能通过to_string、to_ulong、to_ullong转换回去。

  • 不是容器:它没有迭代器,也不能像std::vector那样动态增删元素。如果需要运行时改变长度,应使用std::vector<bool>或boost::dynamic_bitset。


主要接口梳理

构造与初始化
方式说明
bitset<N> b;全部位初始化为0
bitset<N> b(42ULL);用整数的二进制表示初始化右侧若干位,高位补0
bitset<N> b("1010");用'0'/'1'字符串初始化(注意最右侧字符对应最低位b[0])
bitset<N> b(str, pos, n);从字符串的子串构造
元素访问与查询
成员函数作用
b[i]返回第i位的代理引用,可读可写
b.test(i)返回第i位是否为1,带越界检查(越界抛出std::out_of_range)
b.count()返回1的个数(C++23 起有constexpr优化)
b.size()返回N
b.all()/b.any()/b.none()全部为1/ 至少一个为1/ 全部为0
修改操作
操作说明
b.set()/b.set(i)全部置1/ 第i位置1
b.reset()/b.reset(i)全部置0/ 第i位置0
b.flip()/b.flip(i)全部翻转 / 第i位翻转
位运算

std::bitset重载了所有标准位运算符,语义与整数位运算一致:

cpp

auto c = a & b; // 按位与 auto d = a | b; // 按位或 auto e = a ^ b; // 按位异或 auto f = ~a; // 按位取反 auto g = a << 3; // 左移(向高位移动) auto h = a >> 2; // 右移(向低位移动)
转换
  • b.to_string():返回"1010..."形式的字符串。

  • b.to_ulong()/b.to_ullong():转换为无符号整数;如果N大于目标整数类型的位宽,且高位有1,会抛出std::overflow_error。


版本演进:C++23 与 C++26

  • C++23(P2417R2):将std::bitset的绝大多数成员函数标记为constexpr,使其可以在编译期求值中使用。

  • C++26(P2697R0):新增了接受std::string_view的构造函数,并进一步统一了字符串接口。

#include <iostream> #include <bitset> #include <string> int main() { // 1. 从字符串构造(右侧字符是最低位 b[0]) std::bitset<8> a("10110011"); std::cout << "a = " << a << "\n"; // 10110011 // 2. 从整数构造 std::bitset<8> b(0b01011101); // 二进制字面量 C++14 std::cout << "b = " << b << "\n"; // 01011101 // 3. 查询 std::cout << "a[0] = " << a[0] << "\n"; // 1(最低位) std::cout << "a.test(6) = " << a.test(6) << "\n"; // 0 std::cout << "a.count() = " << a.count() << "\n"; // 5 // 4. 修改 a.set(0); // 最低位置 1(本来就是 1) a.reset(1); // 第 1 位清 0 a.flip(7); // 最高位翻转(1→0) std::cout << "a after modification = " << a << "\n"; // 5. 位运算 auto c = a & b; auto d = a | b; auto e = a ^ b; std::cout << "a & b = " << c << "\n"; std::cout << "a | b = " << d << "\n"; std::cout << "a ^ b = " << e << "\n"; std::cout << "~a = " << ~a << "\n"; // 6. 移位(注意方向:<< 向高位索引移动) std::cout << "a << 1 = " << (a << 1) << "\n"; std::cout << "a >> 2 = " << (a >> 2) << "\n"; // 7. 转换回字符串和整数 std::string s = a.to_string(); unsigned long ul = a.to_ulong(); std::cout << "a.to_string() = " << s << "\n"; std::cout << "a.to_ulong() = " << ul << "\n"; return 0; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询