std:byte详解

基础概念

c++17引入了std::byte来表示一个字节,相对于早期版本的char或者unsinged char来表示字节,它的好处是std::byte不是一个字符类型,而使用char或者unsigned char来表示一个字节,会解释为字符类型,它具有如下特点:

  1. 仅支持创建时初始化或复制初始化
  2. 该类型不支持算术运算,比如++、--、+、-、*、/等
  3. 仅支持位运算

其依赖的头文件:#include <cstddef>

std::byte的简单实现:

enum class byte : unsigned char {};

从上面可以看出std::byte本质上是强枚举类型。

使用std::byte的好处是可以明确的区分字符类型和二进制数据类型

基本使用方法

#include <cstddef>

void example()
{
    //创建
    std::byte b1{42};  //正确
    std::byte b2{0xff};    //正确
    std::byte b3 = std::byte{0};  //正确

    // 编译错误的情况
    // std::byte b4 = 42;                // 错误:不允许隐式转换
    // std::byte b5{256};                // 错误:值超出范围
    // std::byte b6 = 0xFF;              // 错误:不允许隐式转换
}

位运算

void byte_operations() {
    std::byte b1{0x0F};  // 0000 1111
    std::byte b2{0xF0};  // 1111 0000
    
    // 位运算
    std::byte result1 = b1 | b2;         // 位或:1111 1111
    std::byte result2 = b1 & b2;         // 位与:0000 0000
    std::byte result3 = b1 ^ b2;         // 位异或:1111 1111
    std::byte result4 = ~b1;             // 位取反:1111 0000
    
    // 移位操作
    std::byte shift1 = b1 << 2;          // 左移:0011 1100
    std::byte shift2 = b1 >> 1;          // 右移:0000 0111
    
    // 复合赋值
    std::byte compound = b1;
    compound |= b2;                       // 位或赋值
    compound &= b2;                       // 位与赋值
    compound ^= b2;                       // 位异或赋值
    compound <<= 2;                       // 左移赋值
    compound >>= 1;                       // 右移赋值
}

类型转换操作

void byte_conversions() {
    std::byte b{0x42};
    
    // 转换为整数类型
    int i = std::to_integer<int>(b);              // 66
    unsigned char uc = std::to_integer<unsigned char>(b); // 0x42
    
    // 从一个类型创建 std::byte
    auto b1 = std::byte{0x42};                    // 直接从字面量
    auto b2 = static_cast<std::byte>(0x42);       // 使用 static_cast
    
    // 在字节数组和其他类型之间转换
    int32_t value = 0x12345678;
    const std::byte* byte_ptr = reinterpret_cast<const std::byte*>(&value);
    
    // 创建字节数组
    std::array<std::byte, 4> bytes;
    std::memcpy(bytes.data(), &value, sizeof(value));
}

从上面的例子可以看到,std::byte类型的变量与其他类型的之间的转换方法。需要显式的进行转换

应用场景

由于std:byte可以明确的表示数据是非字符数据,它的应用场景一般有如下场景:

  • 网络数据接收:如果网络收发发送的是二进制数据,可以考虑使用std::byte进行处理
  • 文件io操作:如果一个文件是二进制数据文件,应该优先考虑使用std::byte

网络协议实现的例子:

class NetworkPacket {
private:
    std::vector<std::byte> packet_data;

public:
    void add_header(uint8_t type) {
        packet_data.push_back(std::byte{type});
    }
    
    void add_payload(const void* data, size_t size) {
        const std::byte* bytes = static_cast<const std::byte*>(data);
        packet_data.insert(packet_data.end(), bytes, bytes + size);
    }
    
    std::vector<std::byte> get_packet() const {
        return packet_data;
    }
};

文件操作的例子:

class BinaryFile {
public:
    static std::vector<std::byte> read_file(const std::string& filename) {
        std::ifstream file(filename, std::ios::binary);
        if (!file) {
            throw std::runtime_error("Cannot open file");
        }
        
        // 获取文件大小
        file.seekg(0, std::ios::end);
        size_t size = file.tellg();
        file.seekg(0, std::ios::beg);
        
        // 读取文件内容
        std::vector<std::byte> buffer(size);
        file.read(reinterpret_cast<char*>(buffer.data()), size);
        
        return buffer;
    }
    
    static void write_file(const std::string& filename, 
                          const std::vector<std::byte>& data) {
        std::ofstream file(filename, std::ios::binary);
        if (!file) {
            throw std::runtime_error("Cannot create file");
        }
        
        file.write(reinterpret_cast<const char*>(data.data()), 
                  data.size());
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值