【发布时间】:2020-08-19 10:39:46
【问题描述】:
我正在尝试将多个索引打包成一个字节(由GIF format 定义):
std::uint8_t global_color_table_flag; // bit [0]
std::uint8_t color_resolution; // bits [1-3]
std::uint8_t sort_flag; // bit [4]
std::uint8_t global_color_table_size; // bits [5-7]
我想用
std::uint8_t field = (global_color_table_flag << 7) |
(color_resolution << 4) | (sort_flag << 3) |
(global_color_table_size);
但是左移运算符<< 将我的std::uint8_t 提升为int 并且编译器抱怨(-Werror)。为什么呢?在int 上使用它不会将其提升为更大的int。如果您不正确地使用它,那只是UB。为什么std::uint8_t 有什么不同?
如果我使用std::byte,则行为符合预期。但是,由于上面提到的问题,代码相当难看:
std::byte global_color_table_flag_byte{global_color_table_flag};
global_color_table_flag_byte <<= 7;
std::byte color_resolution_byte{color_resolution};
color_resolution_byte <<= 4;
std::byte sort_flag_byte{sort_flag};
sort_flag_byte <<= 3;
std::byte global_color_table_size_byte{global_color_table_size};
std::byte packed_field = global_color_table_flag_byte |
color_resolution_byte | sort_flag_byte |
global_color_table_size_byte;
file_stream << std::to_integer<std::uint8_t>(packed_field);
有更好的方法吗?作为一个附带问题,为什么我不能将我的std::byte 写入我的二进制流?我认为这种类型的全部意义在于促进对此类流的操作。
【问题讨论】:
标签: c++ bit-manipulation