别再用 unsigned char 了,std::byte 才是真爱!

开发
想象一下,如果字节是一个演员,那么 std::byte 就是一个纯粹的表演艺术家 - 它只专注于做一件事:表示原始的字节数据。

大家好!今天让我们来聊聊 C++17 中引入的一个有趣的小伙伴 - std::byte!

想象一下,如果字节是一个演员,那么 std::byte 就是一个纯粹的表演艺术家 - 它只专注于做一件事:表示原始的字节数据 ✨

#include <cstddef>

enum class byte : unsigned char {};  // 就是这么简单!

为什么需要 std::byte?🤔

std::byte 与 unsigned char 的关键区别:

#include <cstddef>

// unsigned char - 可以进行算术运算 🚫
unsigned char old = 42;
old = old + 1;     // 允许,但这对字节操作来说不合理!

// std::byte - 只允许位运算 ✨
std::byte modern{42};
// modern = modern + 1;  // 编译错误!
modern = modern | std::byte{1};  // 正确的位运算方式 ✅

本质区别:

  • unsigned char: 被视为数值类型,允许算术运算 🔢
  • std::byte: 纯粹的字节容器,只支持位运算 🎯
  • 这种限制让代码更安全、语义更清晰!💪

玩转 std::byte 🎮

来看看如何玩转这个字节小精灵 std::byte 吧! 🌈

#include <cstddef>
#include <iostream>
#include <bitset>

int main() {
    // 创建一个神秘字节 🎭
    std::byte secret{0b101010};  // 二进制魔法,像变魔术一样 ✨
    
    // 位运算大法 🔮
    std::byte mask{0b111000};    // 这是我们的魔法面具
    auto result = secret & mask;  // 变身! 🎪
    
    // 揭秘时刻! 🎯
    std::cout << "解密结果:"
              << std::bitset<8>(std::to_integer<int>(result)) 
              << " 🎨\n";
}

这段代码就像在玩魔术 🎩:

  • 先准备一个神秘数字 🎲
  • 用魔法面具(掩码)来变形 🎭
  • 最后揭晓神奇的结果 ✨

就是这么简单,就像变魔术一样有趣! 🎪

玩转数字转换 🎮

嘿!想把 std::byte 变成数字吗?有两个超酷的魔法咒语 ✨:

std::byte magic_byte{42};  // 先来个神秘数字 🎲

// 经典魔法 🧙♂️
int num1 = std::to_integer<int>(magic_byte);  // 老牌法术,稳如泰山!

// 新式魔法 ⚡
int num2 = std::to_underlying(magic_byte);     // C++23出品,简单粗暴!

就这么简单!两种方法都能把我们的字节小精灵变成普通数字 🎯

  • to_integer 是老前辈,可靠又稳定 🏰
  • to_underlying 是新秀,代码更短,用起来更爽 🚀

选哪个?看你心情!反正都能帮你完成任务 🎉

位运算大魔法秀 🎪

来看看 std::byte 的位运算绝活吧!就像变魔术一样神奇 ✨:

std::byte b{0b00001111};  // 我们的魔法师 🎩

// 左移仙术 ⬅️
b <<= 1;  // 嗖!数字们向左跑 🏃♂️

// 右移神通 ➡️
b >>= 2;  // 唰!数字们向右溜 🏃♀️

// 三大神器 🔮
std::byte mask{0b11110000};  // 魔法面具准备!
b |= mask;  // 或运算:两个数合体 🤝
b &= mask;  // 与运算:双剑合璧 ⚔️
b ^= mask;  // 异或运算:完美变身 🦸♂️

就这么简单!每个运算都像个小魔术 🎯,让字节变来变去,超级好玩!记住:位运算就是 std::byte 的独门绝技 🥷!

实战小案例:玩转权限控制 🎮

来看个超级实用的例子 - 用 std::byte 玩转权限控制!就像在玩积木一样简单 🧩

// 权限小精灵们 🧚♂️
enumclass Permissions {
    None = 0,     // 啥也不能干 🚫
    Read = 1,     // 可以偷看 👀
    Write = 2,    // 可以写字 ✍️
    Execute = 4   // 可以跑起来 🏃♂️
};

int main() {
    // 创建一个空权限盒子 📦
    std::byte permissions{0};
    
    // 往盒子里放入权限 🎁
    permissions |= std::byte{static_cast<unsignedchar>(Permissions::Read)};   // 放入读权限
    permissions |= std::byte{static_cast<unsignedchar>(Permissions::Write)};  // 放入写权限
    
    // 偷偷看看有没有读权限 🔍
    bool canRead = (permissions & std::byte{static_cast<unsignedchar>(Permissions::Read)}) != std::byte{0};
    std::cout << "能偷看吗?" << (canRead ? "没问题!🎯" : "不行哦~🎲") << "\n";
}

就是这么简单! 🎨

  • 权限就像积木块 🧱
  • 用 |= 把权限放进盒子 📥
  • 用 & 来检查权限是否存在 🔍

一个字节八个位,就能存八种权限,超级省空间! 🚀

记住,std::byte 就像一个专业的杂技演员 - 它只做位运算这一件事,但是做得非常专业!这就是它的美,简单而纯粹 ✨

字节数组操作 - 玩转二进制数据 🎮

来看看如何玩转字节数组,就像在玩积木一样简单! 🧩

#include <cstddef>
#include <vector>

int main() {
    // 开一个神奇的百宝箱 🎁
    std::vector<std::byte> buffer(4);  // 4个格子的魔法盒子
    
    // 放入宝物 ✨
    buffer[0] = std::byte{0xFF};  // 第一格放个满值 💎
    buffer[1] = std::byte{0x00};  // 第二格放个空值 🕳️
    
    // 检查宝物 🔍
    for(constauto& b : buffer) {
        std::cout << std::to_integer<int>(b) << " ";  // 一个一个数数 🎲
    }
}

超简单的三步走 🚀:

  • 准备盒子 📦
  • 放入宝物 💎
  • 查看内容 🔍

就这么简单,字节数组就被你玩转啦! 🎯

与其他类型的转换 - 变形记 🔄

来看看数据类型是如何华丽变身的! ✨

#include <cstddef>
#include <cstring>

int main() {
    // 整数变身魔法 🎩
    int number = 12345;                        // 原始数字 🔢
    std::byte bytes[sizeof(int)];              // 准备魔法容器 🎁
    std::memcpy(&bytes, &number, sizeof(int)); // 变身开始! ✨
    
    // 变身回来 🎭
    int restored;                              // 准备还原容器 📦
    std::memcpy(&restored, &bytes, sizeof(int)); // 还原魔法 🌟
    
    // 见证奇迹的时刻 🎪
    std::cout << "变身前: " << number << " 🎲\n"
              << "变身后: " << restored << " 🎯\n";
}

就这么简单! 🚀

  • memcpy 就是我们的变身魔法棒 🪄
  • 字节数组就像是数据的百变衣柜 👔
  • 想变就变,想换就换,超级方便! 🎨

记住:这种转换就像变魔术一样,要小心使用哦! 🎭

std::byte 使用秘笈 🎯

来看看使用 std::byte 的超级小贴士! 🚀

(1) 初始化有讲究 👑

std::byte good{42};     // 完美! 像个魔法师一样优雅 ✨
std::byte bad = 42;     // 糟糕! 编译器会生气的 🚫

(2) 只能位运算哦 🎮

std::byte b{0x42};
// b = b + 1;          // 不行!这不是计算器 🙅♂️
b |= std::byte{0x01};  // 完美!位运算才是正道 ⚡

(3) 内存小把戏 🎪

std::vector<std::byte> magic(1024);  // 开启魔法空间 🌟
std::fill(magic.begin(), magic.end(), std::byte{0});  // 施展清零术 ✨

记住: std::byte 就像个纯粹的武林高手 🥷

  • 只专注位运算 🎯
  • 拒绝算术运算 🚫
  • 安全又可靠 🛡️

就是这么简单! 一起来玩转字节世界吧! 🎨

性能考虑 - 快得飞起 🚀

嘿!担心 std::byte 会拖慢你的程序吗?放心啦!它轻得像片羽毛 🪶

// 这两行代码就是最好的保证书 📜
static_assert(sizeof(std::byte) == 1, "std::byte 必须是1字节!");    // 大小刚刚好 📏
static_assert(alignof(std::byte) == 1, "std::byte 对齐要求必须是1!"); // 对齐完美 ✨

简单说就是:

  • 体积小:就一个字节,比蚂蚁还小 🐜
  • 零开销:编译器直接优化,快得像闪电 ⚡
  • 对齐稳:不会浪费一丁点内存 💫

所以,放心大胆地用吧!它就是性能小超人 🦸♂️

总结 🎉

std::byte 是现代 C++ 中处理原始字节数据的最佳选择:

  • 类型安全 ✅
  • 语义清晰 ✅
  • 零开销抽象 ✅
  • 防止意外的算术运算 ✅

记住:当需要处理原始字节时,std::byte 就是你的最佳拍档! 🤝

责任编辑:赵宁宁 来源: everystep
相关推荐

2023-10-26 16:33:59

float 布局前段CSS

2020-12-04 10:05:00

Pythonprint代码

2020-12-02 11:18:50

print调试代码Python

2021-06-09 06:41:11

OFFSETLIMIT分页

2021-05-21 13:10:17

kill -9微服务Java

2021-05-25 09:30:44

kill -9Linux kill -9 pid

2020-12-15 08:06:45

waitnotifyCondition

2020-12-03 09:05:38

SQL代码方案

2021-01-29 11:05:50

PrintPython代码

2020-07-17 07:15:38

数据库ID代码

2022-01-27 07:48:37

虚拟项目Django

2022-03-10 10:12:04

自动化脚本Bash

2024-06-12 13:54:37

编程语言字符串代码

2022-10-27 21:34:28

数据库机器学习架构

2019-03-12 14:48:29

路由器XBOXPS4

2023-06-26 08:20:02

openapi格式注解

2023-09-08 08:35:42

层叠样式表CSS

2023-09-14 12:03:30

空指针判空

2020-12-07 06:05:34

apidocyapiknife4j

2020-05-19 17:09:33

Pandas大数据数据分析
点赞
收藏

51CTO技术栈公众号