Live data from Hacker News

Cost of enum-to-string: C++26 reflection vs. the old ways

vittorioromeo.com

61–70 of 189 posts

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#61
post #11

No doubt reflection has been built with other use cases in mind, but it sure would have been nice just to have std::to_string(enum)

C++ conference speakers (including keynotes) are now begging everyone to stop using enum to string in their example. While they are a simple and easy to understand example, reflection is for much more interesting problems. I can't think of any other example that I would type into a comment box or put on a slide.

I mean a readable implementation of tuple with minimal overhead is a great case for me (went from around 1.6k lines to approximately 250 lines). I wrote an implementation including the normally difficult to implement tuple_cat based on c++26 within a few hours.

My favorite thing is that I will get to remove and replace most of the cryptic template recursion stuff I have with "template for" and maybe a bit of reflection. Debugging the unrolled stuff will be a joy in comparison.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#62
post #57

Never quite understood why people are so obsessed with meta programming capabilities in a language, be it templates, comptime, macros, whatever. I program mostly in C, if I need 'meta' programming I just write another C program that processes C source code (I've written a simple C parser), then in my build script I build in two stages, build meta program, run it, build rest of program. Simple, effective, debuggable (…

One obvious answer is that people probably don’t want to write a whole parser and wire up new steps in their build pipeline just to do something simple like get the name of enum cases as a string.

Without taking a stance on whether in-language meta programming facilities are good or bad, it’s not hard to find examples of cases where people find it useful to have them.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#63
post #57

Never quite understood why people are so obsessed with meta programming capabilities in a language, be it templates, comptime, macros, whatever. I program mostly in C, if I need 'meta' programming I just write another C program that processes C source code (I've written a simple C parser), then in my build script I build in two stages, build meta program, run it, build rest of program. Simple, effective, debuggable (…

Writing a C++ parser is much harder than a C parser to the point there had been just 3 parsers used among all C++ compilers for quite a while. So you'd need to use some library for parsing. So now you are looking into the library's parser compatibility with the compiler you are using (it might not support the C++ standard you are on at all, it can have bugs preventing it from parsing the code that the compiler parses just fine) and not just on your code but on the library headers you include in your code. What are you going to do when cindex/libclang or whatever chokes on a libstdc++ header? You also have the issue with builtin macros: are they are the same in your library parser? Most likely not. Good luck testing all that.

Two-stage compilation is just a bonus on top: you add a sequential dependency in your build graph and if you have enough of these parsing programs you are going to wait till they are all built before your build can go wide.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#64

Earlier quoted context omitted.

It is "cryptic" and "ugly" to you just because you're not familiar with it. You'd pick the macro-based implementation because you are familiar with it. Seeing this argumentation is so tiresome, because it feels like there is a lack of self-awareness regarding what is "familiar" and what isn't, which is subconsciously translated to "ugly" and "bad".

Have you ever used other (modern) programming languages ? In a lot of languages, you achieve the same with 1 line of code. It's not about familiarity, it's about the fact that it's a long and convoluted incantation to get the name of an enum. Why do I have to be familiar with all those weird symbols just to do a trivial thing ? Update: Zig: const Color = enum { red, green, blue }; const name = @tagName(Color.red); //…

And what if you want to implement something like Rust's "derive"? That is what the article shows.

As far as I understand you would have to mess with individual parser tokens in Rust instead of high-level structures like "enum" (C++ reflection). It would be much, much uglier to implement anything like "to_enum_string" in Rust as you would have to re-implement parts of the compiler to get the "enum" concept out of a list of tokens.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#65
post #52

Earlier quoted context omitted.

C++: enum Color { red, green, blue }; auto name = to_enum_string(Color::Red); // "Red"

... and where does that `to_enum_string` come from exactly? It doesn't seem to be built-in, which is the point of the parent comment.

The whole point of reflection is that it doesn't have to be builtin.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#67
post #60

Earlier quoted context omitted.

...so what? It's just a header you have to #include.

By that logic why would anything have to be standardised?

The question is whether something belong in the language or in a library (possibly the standard library).

A guiding principle of C++ is that if something can be implemented cleanly and efficiently in a library, the language should not be extended to support the use case.

Now boost.pfr is exceedingly clever, but relying on speculative pack expansions or using stateful metaprogramming hacks is not something I would call clean and efficient, so proper reflection is warranted.

I do worry about the compile time impact though.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#68
post #2

Oof, that first example (the idiomatic C++26 way) looks so foreign if you're mostly used to C++11.

I was very curious to see what C++ 26 brings to the table, since I haven't used C++ in a while. When I saw the 'no boilerplate' example, the very first thought that came to my mind: This is the ugliest, most cryptic and confusing piece of code I've ever seen. Calling this 'no boilerplate' is an insult to the word 'boilerplate'. Yeah, I can parse it for a minute or two and I mostly get it. But if given the choice, I'd…

> But if given the choice, I'd choose the C-macro implementation (which is 30+ years old) over this, every time.

Why? The implementation is not pretty, but you only need to write it once and then it works for all enums. The actual usage is trivial, it's just a function call.

The C macro version is horrendous in comparison. Why would I want to declare my enums like that just because I might want to print them?

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#69
post #51

Earlier quoted context omitted.

I think this is a very bad take -- once you write it by hand you have to manually keep it in sync with the actual struct and ensure you made no mistakes. Reflection guarantees 1-1 future-proof mapping with the actual C++ struct, avoids boilerplate, and ensures that the serialization logic is correct.

The protocol is important though, not the internal structure. When you only have exactly one version of a program talking to the same version of itself you don't care. However when you are mixing versions or worse programming language (and thus can't mix structs which are implementation details of your language) the protocol is what matters. That is if you are worried about doing this by hand reflection is not the an…

I completely understand your point. Then again you might be able to use reflection to verify that your manually rolled implementation actually serializes all fields.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#70
post #57

Never quite understood why people are so obsessed with meta programming capabilities in a language, be it templates, comptime, macros, whatever. I program mostly in C, if I need 'meta' programming I just write another C program that processes C source code (I've written a simple C parser), then in my build script I build in two stages, build meta program, run it, build rest of program. Simple, effective, debuggable (…

This works for extreme needs.

But you're probably not doing s ton of metaprogramming all the time like you should be, and would with a language that allows it.

The lack of metaprogramming is also why C is so slow compared to C++

Post reply on HN