Reputation: 16156
Suppose I have an enum:
enum class Thing : std::uint8_t {
Foo = 21,
Bar = 42,
Baz = 1
};
I want to convert a "raw" value (of the underlying type) to a value of that enum, with error handling catching values which are not "a thing". I could use checks like if (raw_value == static_cast<std::uint8_t>(Thing::Foo))
and then an else
with the error handling, but then I could forget for example Thing::Baz
. However, when I switch over a value of type Thing
, then my compiler (as probably most modern compilers) warns me about unhandled enumeration values ("enumeration value Baz
not handled in switch").
So I came up with this:
Thing thingFromUInt8(std::uint8_t const b) {
Thing const t = static_cast<Thing>(b);
switch (t) { // If I'd add Thing::Frob but forget it here I get a warning
case Thing::Foo:
case Thing::Bar:
case Thing::Baz:
return t;
}
throw std::runtime_error("That's not a thing...");
}
Questions:
Upvotes: 6
Views: 1296
Reputation: 275370
It is legal C++.
The drawback is the DRY violation, but avoiding it is difficult.
In c++23 we'll have reflection and be able to generate equivalent code (without having to rely on compiler warnings to make sure we didn't miss any). Reflection syntax is still a bit in flux, but every version I have read over was able to handle that problem.
Upvotes: 3