Live data from Hacker News

Enum class improvements for C++17, C++20 and C++23

cppstories.com

51–60 of 121 posts

Re: Enum class improvements for C++17, C++20 and C++23

#51
post #36

Earlier quoted context omitted.

Just use std::variant References in C++ are just sugary pointers.

References have one important property over pointers. They cannot be null.

const ref lifetime extension is important to, or operator overloading wouldn't be workable.

Re: Enum class improvements for C++17, C++20 and C++23

#52

Speaking of enums, what's a better serialization framework for C++ like Serde in Rust, and then what about Linked Data support and of course also form validation. Linked Data triples have (subject, predicate, object) and quads have (graph, subject, predicate, object). RDF has URIs for all Subjects and Predicates. RDF Objects may be URIs or literal values like xsd:string, xsd:float64, xsd:int (32bit signed value), xsd…

Glaze (https://github.com/stephenberry/glaze) is great if you have C++20 and want JSON or CSV. Compile time reflection is built in.

Re: Enum class improvements for C++17, C++20 and C++23

#53
post #9

enum class Handle : uint32_t { Invalid = 0 }; Handle h { 42 }; // OK One of their examples demonstrates the number one issue for me with enums, which was not fixed with `enum class`. Since values outside the range of the type are valid, you are constantly needing to check for invalid values in any function that takes an enum [class]. Ruins any attempt at "parse, don't validate" style in c++ and completely ruins the "…

That's by design. Consider mapping a file or reinterpret casting a network buffer that contains a structure with such an enum: if has been written by a different version of an application, the possible enum values might be different. That was considered, among other thing, an important use case to support.

You can easily build your own safe enum on top of you really want.

Edit: someone else pointed out the bitmask use case else thread. Strongly typed integrals is also a common use case.

Re: Enum class improvements for C++17, C++20 and C++23

#55
post #36

Earlier quoted context omitted.

Just use std::variant References in C++ are just sugary pointers.

References have one important property over pointers. They cannot be null.

they easily can :)

void test(int& y){}

int main() { int* x = nullptr; test(*x); }

Re: Enum class improvements for C++17, C++20 and C++23

#56
post #16
post #9

enum class Handle : uint32_t { Invalid = 0 }; Handle h { 42 }; // OK One of their examples demonstrates the number one issue for me with enums, which was not fixed with `enum class`. Since values outside the range of the type are valid, you are constantly needing to check for invalid values in any function that takes an enum [class]. Ruins any attempt at "parse, don't validate" style in c++ and completely ruins the "…

Well, apparently it was fixed with `enum class`… until it was un fixed in C++17 for unfathomable reasons. It’s honestly crazy that C++ doesn’t have simple exhaustiveness-checked enums. The obvious actual solution for the valid use case of deserializing an enum from an integer would be something like template std::optional from_underlying(std::underlying_type ) requires(std::is_enum_v )

It wasn't unfixed in C++17. The problem existed before C++17.

This is valid code in C++11:

    enum class Foo : int { Invalid = 0 };
    Foo f = Foo(5);
In C++11, this compiles with Foo(5) but not Foo{5}. In C++17, this compiles with both Foo(5) and Foo{5}.

Re: Enum class improvements for C++17, C++20 and C++23

#57
post #7

Odd that it says auto value = std::to_underlying(p); // C++23 is "more expressive" than uint8_t value = static_cast (Permissions::Read); The latter seems clearly more expressive, not less. You could tighten it up a bit by using auto on the LHS instead of the redundant uint8_t. In the former I don't know what's going on and I have to go read another header to figure out the type of `value`.

The first is expressive in that you know that the "value" variable definitely ends up with the underlying numerical type of the Permissions enum, whereas in the second perhaps that static_cast is changing from a different numeric type.

Re: Enum class improvements for C++17, C++20 and C++23

#58
post #9

enum class Handle : uint32_t { Invalid = 0 }; Handle h { 42 }; // OK One of their examples demonstrates the number one issue for me with enums, which was not fixed with `enum class`. Since values outside the range of the type are valid, you are constantly needing to check for invalid values in any function that takes an enum [class]. Ruins any attempt at "parse, don't validate" style in c++ and completely ruins the "…

I don't know C++ too deeply but from the little bit in the article, it seems like these `enum class` enums are actually Newtypes with associated constants instead of actual enumerations. They clearly don't 'enumerate' all possible values but they do give different behavior from their underlying type.

Is it possible to override the constructor so it limits the allowed values? Implement other methods on the `enum class`? If so then that makes them still very useful, albeit not in the usual `enum` sense.

Re: Enum class improvements for C++17, C++20 and C++23

#59

Earlier quoted context omitted.

References have one important property over pointers. They cannot be null.

they easily can :) void test(int& y){} int main() { int* x = nullptr; test(*x); }

There is a difference between an API promissing that a value wont be null and a buggy program setting a null where it should not. A reference is only null if someone fucked up. As a programmer you can usually rely on a reference not being null and you couldn't do anything about it if it was anyway within the constraints of the language.
Post reply on HN