C++26 Expansion Tricks
pydong.org
pydong.org
It feels like I'm looking at a conlang instead of C++.
Not hating the author, I'm sure they know their stuff and this is useful to someone. Just looking at this from the perspective of an ordinary C++ programmer, it looks very alien.
using ret_t = first_non_void<decltype(fnc.template operator()<Elts>())...>;constexpr void operator>>(F fnc) const { (fnc.template operator()<Elts>(), ...); }
I think C++26's reflection is likely to be one of the most important changes to the language in a very long time.
Still a reflect keyword could have worked. Some argued that in reflection heavy code you would reflect a lot and the keyword would be a lot of noise.
I don't know if the reflection papers have been voted in already (I forgot how to check), so the syntax might still be up for debate.
> The original TS landed on reflexpr(...) as the syntax to reflect source constructs and [P1240R0] adopted that syntax as well. As more examples were discussed, it became clear that that syntax was both (a) too “heavy” and (b) insufficiently distinct from a function call. SG7 eventually agreed upon the prefix ^ operator. The “upward arrow” interpretation of the caret matches the “lift” or “raise” verbs that are sometimes used to describe the reflection operation in other contexts.
I had the impression that the vast majority of us regular users just wanted quality of life improvements: better error messages, networking library, a standard package manager etc. Literally most of what C++ code styles are concerned with is about picking what features are banned in that particular style.
But instead of doing something pratical, the commitee always went with the route of adding increasingly niche features citing that useful things are "out of scope" or "implementation defined" or "userspace".
So what you get is incompatible ecosystems and cultures for an extremely complicated language.
Very happy working with Go presently, where exactly the opposite approach is being taken by maintainers. Eg: There was huge pushback regarding generics introduction (a genuinely useful language feature IMO), but they introduced very good vulnerability scanning (govulncheck) without me even hearing about it being under development.
But my point is that niche (in my opinion) features seem to be getting into the standard much more often than things that are broadly useful (in my opinion).
With C++26 we're barely getting to where python was already in 2001 with the introduction of decorators or Java in 2004 with annotations. C# had these features from the very beginning (albeit at runtime, not compile-time like C++).
How is it okay that newly added language features end up unused/deprecated/discouraged, but it's a problem for libraries?
I never got to try exceptions and modules in C++.
Exceptions because every place I worked at banned them, and modules because they were not implemented by the time I left the language.
I'm 100% sure that people got (and will keep getting) much more value out of unfortunate std::regex and std::fstream than they will ever get from reflection (in the few places that will even allow using it at all).
Everywhere I worked we also had custom ad-hoc reflection/code synthesis, usually via preprocessing. We would have replaced with a builtin solution in an heartbeat.
you work likely in a very specific niche as no language feature has ever been entirely banned in the places I've been to. There are hundreds of thousands of codebases happily using exceptions in C++. https://github.com/search?q=%22throw+std%3A%3Aruntime_error%... as well as any other feature you can imagine.
``` void print_members(T const& obj) { [:expand(nonstatic_data_members_of(^^T)):] ```
What is this ^^?
However many of us would have prefered reflect(T), but again many on WG21 seem to use notepad for programming and don't like to type.
It means the reflection data of the type.
Which… were never added to C++, right? What a mess.
Personally I would rather have reflect.
Why does that matter?
> many of us would have prefered reflect(T), but again many on WG21 seem to use notepad for programming and don't like to type.
I don't know about anyone else, but I find reflect(T) much easier to type than ^^T. I have a high error rate on hitting 6. Not only that I have to move my hand from the home row to hit it.
Ultimetely that is how ISO driven languages work, features get decided by those willing to join the process, and vote on what features become part of the next language standard.
https://github.com/search?q=lang%3AObjective-C%2B%2B+&type=r...
all of those would instantly break.
I develop a C++ / Qt software that also ships on macOS and some parts of the macOS API are only realistically useable from Obj-C / Obj-C++ so any C++ software that wants deeper integration with the OS there must work with Objective-C++.
If you want to enumerate over a bunch of items to print them out, do that. Don't wrap it up in some obscure language feature.
Stuff like this is why, of the two main "C with classes" extension languages, I prefer ObjC over C++. If I really need the speed of C++, I can just use it, but you'd better believe it'll be straightforward C++/STL. At all other times, it's easier to grok ObjC, easier to work with it, and (again) the cognitive load over and above 'C' is really minimal compared to C++.
I guess I'm just one of the old-fashioned folks who think that just because something was difficult to write, it shouldn't be difficult to read. Code clarity wins over brevity in my book any day.
I treat template metaprogramming in C++ like macro code in Lisp - it's not something I use all the time and it's often more complicated than every day code, but used well it make the rest of the codebase simpler to understand.
The most complicated template I've written recently wraps a vendor's clunky old iterator classes (unrelated to STL) with .Current() and .Next() methods, and lets us use them in C++11's `for (auto thing : VendorIterator)` loops. In the vendor's defense, they started writing the library in the early 90s, before the STL was formally part of C++ - though it would be nice if they provided a template like this themselves.
In any case, the template greatly simplifies using the iterators (5 lines of code goes to 1) in dozens of places, at the cost of a complicated template that rarely needs to change. To me it's a fair tradeoff.
Also, had it not been for NeXT's reverse acquisition of Apple it would have been long forgotten by now.
# Primary Warning Set
-Wall -Wextra
# Enhanced Warning Sets
-Wpedantic -Weffc++
# Type Safety
-Wshadow -Wold-style-cast -Wcast-align -Wconversion -Wsign-conversion
-Wdouble-promotion -Wimplicit-fallthrough=5 -Wlogical-op -Wuseless-cast
-Wlifetime -Wsuggest-final-types -Wsuggest-final-methods -Wzero-as-null-pointer-constant
# C++ Features
-Wcatch-value=3 -Wctad-maybe-unsupported -Wdeprecated-copy-dtor
# Memory and Object Safety
-Wdangling-reference -Wpessimizing-move -Wredundant-move -Wclass-conversion
-Wuse-after-free=3 -Wmismatched-new-delete
# Declaration Consistency
-Wmismatched-tags -Wredundant-tags -Wredundant-decls -Wnon-template-friend
-Wattribute-alias=2
# Advanced Analysis
-Wstrict-aliasing=3 -Wstrict-overflow=5 -Warray-bounds=2 -Wzero-length-bounds
-Wnrvo -Winterference-size
# Attribute Suggestions
-Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=noreturn
-Wmissing-noreturn
# Miscellaneous
-Warith-conversion -Wundef -faligned-new
# Static Analysis
-fanalyzer -Wanalyzer-too-complexBetter not to do this. Cast the operand to void first. Otherwise if someone overloads operator, (the wisdom of that is another matter) it will affect the behavior.
It seems very esoteric, hard to understand.
Some of the examples don't even compile, but in any case, this isn't the working man's C++.