Date: Fri, 26 Jun 2026 10:08:32 +0100
On Fri, 26 Jun 2026 at 09:25, Jan Schultke via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>>
>> 2. In generic code, while you can actually bitshift a std::byte, it eg. acts as an enumeration type and returns false with std::is_integral, std::is_fundamental, and so on - highlighting a few issues with using it with generic code
>
>
> I don't really see the problem. You'd need to provide a concrete example.
Right. You can't just say "generic code" as though that explains it. I
agree that you can't use std::byte in generic code that wants to work
with integer types and fundamental types ... so what? It's not an
integer. That's good.
And I don't think I've ever needed to use std::is_fundamental. Why are
you writing generic code that depends on that property? Maybe you want
std::is_scalar instead?
>
>>
>> 3. The idea to have a type to correctly represent "raw data" is good - it is the design or implementation if you will, that is lacking, and it should interop easier with other things (like conversions) and work better in generic code - right now it it way too restrictive and cumbersome, to the point it is prohibiting adoption.
>
>
> Bit-shifting arguably should have never been added to std::byte (nor any other operators, but shifting is particularly bad). The rationale for not providing arithmetic operators like multiplication is that it's just meant to be a "bag of bits", but left-shifting is defined as multiplying with a power of two, so it makes very little sense that you can multiply using << 1 but not using * 2.
This seems like a very poor argument. Just because you can perform an
operation which has the same result as multiplication or division by
the very special case of 2 doesn't mean the type should support
multiplication with arbitrary values. And just because you can't
multiply with arbitrary values doesn't mean you shouldn't be able to
perform bitwise shifts on a bag of bits type. Bit-shifting on a byte
type makes perfect sense to me.
>
> My main issue with std::byte ergonomics is the initialization. You cannot do things like
>
> constexpr std::byte png_magic_bytes[] {
> 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
> };
>
> ... to help with checking whether some byte buffer is a PNG file.
Yes, this is frustrating. A UDL for bytes could help, a little. But it
would be horribly verbose (and a 'B' suffix wouldn't work).
> You also can't use std::byte for anything related to I/O. It won't work with std::fwrite, std::ostream, etc. forcing you to use reinterpret_cast all over the place if you want to do anything useful with it.
>
> Some people may argue that it's not intended to be used as an "I/O byte" but only to introspect C++ objects, but then the motivation for this type is so microscopic that it should have never been added to C++. The tiny amount of C++ code that deals with inspecting bytes of an object can just use unsigned char.
We've deprecated I/O for unsigned char too.
<std-proposals_at_[hidden]> wrote:
>>
>> 2. In generic code, while you can actually bitshift a std::byte, it eg. acts as an enumeration type and returns false with std::is_integral, std::is_fundamental, and so on - highlighting a few issues with using it with generic code
>
>
> I don't really see the problem. You'd need to provide a concrete example.
Right. You can't just say "generic code" as though that explains it. I
agree that you can't use std::byte in generic code that wants to work
with integer types and fundamental types ... so what? It's not an
integer. That's good.
And I don't think I've ever needed to use std::is_fundamental. Why are
you writing generic code that depends on that property? Maybe you want
std::is_scalar instead?
>
>>
>> 3. The idea to have a type to correctly represent "raw data" is good - it is the design or implementation if you will, that is lacking, and it should interop easier with other things (like conversions) and work better in generic code - right now it it way too restrictive and cumbersome, to the point it is prohibiting adoption.
>
>
> Bit-shifting arguably should have never been added to std::byte (nor any other operators, but shifting is particularly bad). The rationale for not providing arithmetic operators like multiplication is that it's just meant to be a "bag of bits", but left-shifting is defined as multiplying with a power of two, so it makes very little sense that you can multiply using << 1 but not using * 2.
This seems like a very poor argument. Just because you can perform an
operation which has the same result as multiplication or division by
the very special case of 2 doesn't mean the type should support
multiplication with arbitrary values. And just because you can't
multiply with arbitrary values doesn't mean you shouldn't be able to
perform bitwise shifts on a bag of bits type. Bit-shifting on a byte
type makes perfect sense to me.
>
> My main issue with std::byte ergonomics is the initialization. You cannot do things like
>
> constexpr std::byte png_magic_bytes[] {
> 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
> };
>
> ... to help with checking whether some byte buffer is a PNG file.
Yes, this is frustrating. A UDL for bytes could help, a little. But it
would be horribly verbose (and a 'B' suffix wouldn't work).
> You also can't use std::byte for anything related to I/O. It won't work with std::fwrite, std::ostream, etc. forcing you to use reinterpret_cast all over the place if you want to do anything useful with it.
>
> Some people may argue that it's not intended to be used as an "I/O byte" but only to introspect C++ objects, but then the motivation for this type is so microscopic that it should have never been added to C++. The tiny amount of C++ code that deals with inspecting bytes of an object can just use unsigned char.
We've deprecated I/O for unsigned char too.
Received on 2026-06-26 09:08:49
