0

0

C++中的std::bitset如何处理位运算?(方便地进行二进制位管理)

冰火之心

冰火之心

发布时间:2026-01-11 15:42:08

|

470人浏览过

|

来源于php中文网

原创

std::bitset的位运算符已重载,要求操作数长度一致;整数转换需注意低位截断;不可与原生整数直接混合运算;适用于编译期定长场景。

c++中的std::bitset如何处理位运算?(方便地进行二进制位管理)

std::bitset 的位运算符直接可用,无需手动实现

std::bitset 是值语义类型,operator&operator|operator^operator~ 全部重载完成,结果仍是 std::bitset。它不依赖 <algorithm></algorithm> 或循环,所有操作在编译期确定大小、运行时单指令(或极小指令序列)完成。

常见误用是试图对不同长度的 bitset 做运算:std::bitsetstd::bitset 无法直接运算,编译报错 —— 类型不匹配,不是隐式截断或扩展。

  • 运算双方必须模板参数完全一致,比如 std::bitset a, b; 才能写 a & b
  • 赋值运算符(&=, |=, ^=)同样要求左右操作数类型相同
  • ~a 是逐位取反,结果长度与 a 相同,高位补 1 是自然行为(例如 std::bitset("0010") 取反得 "1101"

如何安全地把整数转成 bitset 并参与运算

std::bitset 构造函数接受 unsigned long long,但注意:只取低 N 位(N 是模板参数),高位被静默丢弃。这不是 bug,是设计使然 —— 它不负责范围检查。

比如 std::bitset b{17}; 得到的是 "0001"(因为 17 的二进制是 10001,只保留低 4 位 0001)。若你本意是“用 4 位表示 17”,这已经越界,需提前校验。

立即学习C++免费学习笔记(深入)”;

  • 转换前建议用 if (x >= (1ULL 判断是否溢出(<code>N 是 bitset 长度)
  • 从字符串构造更可控:std::bitset{"10101010"},但字符串内容必须全为 '0''1',否则抛 std::invalid_argument
  • 不要用 static_cast<:bitset>>(x)</:bitset> —— 没有这种转换,编译失败

bitset 与原生整数混合运算时的陷阱

不能直接写 my_bitset & 0xFF。因为 0xFFint,而 std::bitset 没有针对整数类型的 operator& 重载。编译器不会自动构造临时 bitset,而是报错:“no match for ‘operator&’”。

正确做法是显式构造一个同长度的 bitset:

std::bitset<8> flags{0b10100011};
auto masked = flags & std::bitset<8>{0xFF}; // ✅

如果硬要和变量混合,推荐封装一层:

template<size_t N>
constexpr std::bitset<N> as_bitset(unsigned long long x) {
    return std::bitset<N>{x};
}
// 用法:flags & as_bitset<8>(0x3F);
  • 别依赖 to_ulong() 再运算 —— 这会丢失高位(超出 unsigned long 范围时抛异常),且多一次拷贝
  • 对齐长度是关键:std::bitset & uint32_t 必须先转成 std::bitset,不能靠隐式转换

性能和适用边界:别把它当动态位容器用

std::bitset 所有长度必须在编译期确定,底层通常用一个或多个 unsigned long 存储。这意味着它极快(常数时间位运算、count() 可用内置 popcnt 指令),但也意味着无法 resize、不能 move-only、不支持迭代器遍历(只有 operator[] 随机访问)。

如果你需要运行时决定位数、频繁增删位、或需要 STL 容器接口(如 push_back),std::bitset 不合适 —— 改用 std::vector<bool></bool>(注意其空间特化)或第三方库如 boost::dynamic_bitset

真正适合它的场景很明确:协议字段解析、状态标志集、编译期已知尺寸的掩码计算 —— 比如管理 32 个硬件寄存器位、TLS 握手标志位、或哈希布隆过滤器的固定大小位数组。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

241

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

150

2025.10.17

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

846

2023.08.22

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

203

2023.11.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 6.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号