8

Since std::byte is by definition not an integral type, the following fragment is ill-formed:

enum class foo : std::byte
{
    bar = 1,
    baz = 2
};

Is there a way in C++17 to do something equivalent to this?

Edit: I'm not trying to solve any particular problem. Obviously enum class whatever : unsigned char would do it. However, I was expecting std::byte to be a little more flexible and wanted to know whether this is possible at all.

3442
  • 8,248
  • 2
  • 19
  • 41
  • 3
    Use `unsigned char` as the underlying type? – M.M Dec 12 '17 at 23:18
  • Why would you want to use `std::byte` as an enum underlying type? (or use it at all, for what that matters) – Matteo Italia Dec 12 '17 at 23:21
  • 1
    What's the problem you're trying to solve? – Barry Dec 12 '17 at 23:28
  • @Barry: I'm not trying to solve any particular problem. Just thought that `std::byte` would have been nice to have as the underlying type in the `enum class`es for a binary protocol code I was modernizing today. – 3442 Dec 13 '17 at 02:24
  • @Barry: At first impression, `std::byte` seems to be a way to manipulate memory at the bit level without the inconsistency of it being interpretable as text or numeric data for the sake of backwards-compatibility. However, to do so the standard had to define it as `enum class byte : unsigned char`. As a result, you can't have a "enum class of bytes", so to speak. Hence, either you manipulate `std::byte`s using hard-coded magic values, `static_cast<>` your way around, or not use `std::byte` at all. To me, this seems to defeat its usability in working with binary protocols and formats. – 3442 Dec 13 '17 at 03:12

2 Answers2

13

std::byte is defined by the standard to be an enum class. Therefore, it has an underlying type (of unsigned char). So you can create an enum with the same underlying type:

enum class foo : std::underlying_type_t<std::byte>
{...};
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    That seems like a very un-useful definition of "byte". Sometimes the decisions of the C++ standards committee mystify me. – Mark Ransom Dec 13 '17 at 00:10
  • 1
    @MarkRansom: It matches the use that they want it to have. 1) it's not an integer type, so integer literals don't convert to it and it is certainly not a character. 2) it has well-defined *explicit* conversions from integers, so you can still use integers. 3) it is a distinct type from all other types, so you can overload operators for various byte-specific uses. – Nicol Bolas Dec 13 '17 at 00:13
  • 1
    @NicolBolas: Maybe it was modeled around too constrained use cases? I mean, your proposed solution is the same as `enum class foo : unsigned char` (albeit with an extra bit of intention given to the reader). Obviously that would do it, but still seems to me to be a hack around a flaw in `std::byte`s design. – 3442 Dec 13 '17 at 02:28
  • 3
    @3442: But `byte` is not supposed to be an integer; that's kinda the point of the type. So a better question is why you want to create an enumeration that uses `byte` as its underlying type. – Nicol Bolas Dec 13 '17 at 02:30
  • @NicolBolas: Conceptually, an enumeration might be made up of elements other than integers, kind of like a set, as long as you can define some kind of strict weak ordering among its elements. However, the standard's definition of `enum class` mandates that all underlying types must be integral. I was intending to use `byte` in the spirit of the former definition. – 3442 Dec 13 '17 at 03:39
3

You can use unsigned char or uint8_t instead.

Eyal Cinamon
  • 939
  • 5
  • 16