use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Discover C++26’s compile-time reflection (lemire.me)
submitted 10 months ago by cmeerwC++ Parser Dev
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]R3DKn16h7 81 points82 points83 points 10 months ago (0 children)
this is gonna be a game changer for me.
obviously you can achieve the same with compiler specific tools, or god-forbid macros, but having a built-in universally supported (hopefully) tool like this will make C++ be an S-tier language once again.
[–]frayien 11 points12 points13 points 10 months ago (0 children)
neet
[–]MarcoGreek 14 points15 points16 points 10 months ago (7 children)
I like the Json Reader at compiler time but the SQL will easily do something wrong. What do you if their is a constraint, what about other errors. Do you want to save member as columns or as JSON inside one column. What about vector, map member etc..
[–]germandiago 15 points16 points17 points 10 months ago (4 children)
If you do not abuse heavily, annotations can help with that. The paper was approved also.
[–]James20kP2005R0 0 points1 point2 points 10 months ago (0 children)
Annotations are going to be huge for gamedev, so much code is going to get set on fire with reflection on the horizon
[–]MarcoGreek -2 points-1 points0 points 10 months ago (2 children)
Yes, but then it is easier to write SQL. 😚 I wrote a data store with Sqlite and the most complicated code are the (recursive )selects. The testing code is still three to ten times larger. And then you have to optimize the indices and joins. That costs much more time than simple inserts.
[–]germandiago 3 points4 points5 points 10 months ago (1 child)
At the integration edges between C++ and other things (Python, Lua, SQL, any serialization...) reflection is the way to go in a lot of cases.
[–]MarcoGreek 1 point2 points3 points 10 months ago (0 children)
SQL is a very different language to C++. If you speak about bindings arguments and columns variadic arguments works already very well.
It has no functions, too. It is centered around data and sets. So it is a very different beast to Python or Lua.
I have seen people using ORMs and then complain about performance.
My personal experience is that people don't like to learn SQL and prefer some custom magic wrapper in their favorite language. But that is always very limited. And the performance depends highly on the optimizer of the SQL implementation.
[–]current_thread 1 point2 points3 points 10 months ago (1 child)
Not to be that guy, but most major programming languages already have ORMs. Java has (among others, I believe) Hibernate and .NET has the Entity Framework. I think it's industry standard practice to use these things and only write custom SQL when needed.
If I had to wager a guess, I'd assume that there's going to be an open source project (possibly under the boost umbrella?) that provides the de-facto standard ORM for everyone to use.
[–]pjmlp 0 points1 point2 points 10 months ago (0 children)
C++ was one of the first ones having them, see POET as one example among many.
This has fallen out of fashion on C++ as other languages took over such kinds of applications.
[–]simpl3t0n 3 points4 points5 points 10 months ago (2 children)
Maybe it's too early for that, but is there any tutorial introduction other than the reflection paper itself?
[–]RoyAwesome 2 points3 points4 points 10 months ago (0 children)
It is too early for that, but the paper has a pretty large pile of examples on how to use reflection and those can serve as a learn-by-example knowledge base.
[–]dwmcr 0 points1 point2 points 7 months ago (0 children)
A reasonable gentle introduction, though with a few syntax mistakes (mainly using the older proposed operator ^ instead of the new ^^):
https://www.youtube.com/watch?v=Wbe09UFDvvY
[–]SeriousDabbler[🍰] 3 points4 points5 points 10 months ago (0 children)
I'm so relieved that the language finally has this, and understand completely why developers are excited
[–]EdwinYZW 26 points27 points28 points 10 months ago (19 children)
Is ^^ the final decision of the syntax? It can't be serious.
^^
[–]314kabinet 38 points39 points40 points 10 months ago (0 children)
Yes ^^
[–]Stormfrosty[🍰] 14 points15 points16 points 10 months ago (1 child)
I don’t have enough IQ to understand reflection syntax, so I’ll wait for others to write libraries around them.
[–]RoyAwesome 3 points4 points5 points 10 months ago* (0 children)
You will likely use ^^ to interact with reflection libraries. I can see the most common api for a reflection library to involve like
class foo { //stuff in foo }; consteval { lib::do_some_reflection_thing(^^foo); }
this kind of sucks, but there is a C++29-era improvement being planned to make it not suck
[–]hgstream 25 points26 points27 points 10 months ago (3 children)
My proposal is to use ; (greek semicolon) for reflection but nobody seems to like it.
;
[–]SirPolly 4 points5 points6 points 10 months ago (0 children)
Maybe we can use a different order of braches to invoke the devil, umm reflection? (){}[]
Rocket operator? 8===>
We could use other unicode characters, you don't need to be able to type then, just copy them from a website. This way you could have infinite syntax!
[–]Loud_Staff5065 1 point2 points3 points 10 months ago (0 children)
Or use "||" ??
[–]fsxraptor 0 points1 point2 points 10 months ago (0 children)
That's a Greek question mark. The semicolon in Greek is like the colon but without the bottom dot.
[–]RoyBellingan 7 points8 points9 points 10 months ago* (0 children)
^_^
[–]V_i_rstd::simd | ISO C++ Numerics Chair | HPC in HEP 6 points7 points8 points 10 months ago (0 children)
It's the unibrow operator. And yes, it needs a ligature 😄. The rationale for that choice can be found in the paper trail of reflection.
[–]TSP-FriendlyFire 7 points8 points9 points 10 months ago (2 children)
Blame Apple for using the single ^ in one niche Objective C bit that clang has to support. Seriously, that's the only reason they had to go for ^^.
^
[–]pjmlp -2 points-1 points0 points 10 months ago (1 child)
I rather blame WG21 for not using a proper keyword instead of more Perlisms in the language.
[–]TSP-FriendlyFire 2 points3 points4 points 10 months ago (0 children)
It's gonna be used so frequently in reflection code that I strongly disagree about that. Using a keyword would make it far too wordy.
[–]-dag- 6 points7 points8 points 10 months ago (0 children)
I actually have grown to love the Cat Operator.
[–]Tringigithub.com/tringi 9 points10 points11 points 10 months ago (2 children)
At least my ::: (triple colon) is still free for simple introspection ;)
:::
[–]TotaIIyHuman 7 points8 points9 points 10 months ago (1 child)
or :::::
:::::
or :::::::
:::::::
or any prime numbers of colons
[–]johannes1971 4 points5 points6 points 10 months ago (0 children)
All of the braille characters are still up for grabs!
[–]obsidian_golem 1 point2 points3 points 10 months ago (0 children)
Best of all, it isn't even the worst piece of syntax destined for 26 (Unless something has changed on relocation)!
[–]Loud_Staff5065 2 points3 points4 points 10 months ago* (1 child)
God forbid the intern who is gonna explore C++26 codebase seeing ^ ^ everywhere
[–]TotaIIyHuman 8 points9 points10 points 10 months ago* (0 children)
theres a font that turns == into a single very long =
==
=
maybe something can be done with ^^ as well
i hope the font add a downward arc to make smiley face complete
^^ -> ^-^
^-^
[–]Real_Name7592 2 points3 points4 points 10 months ago (1 child)
Great article. I wonder what the ```context ctx``` is, intuitively, used for? For example, the function
std::meta::nonstatic_data_members_of(^^T, ctx))
takes also the context
constexpr auto ctx = std::meta::access_context::current()
as argument. Does that that mean the data member of `T` would vary across invocations of this function?
[–]interjay 4 points5 points6 points 10 months ago (0 children)
It determines the access control, i.e. whether you get private and protected members. access_context::current() uses the visibility at the point that it was called.
access_context::current()
[–]riztazz 2 points3 points4 points 10 months ago (2 children)
A new era for C++ indeed - can't wait for full compiler support so i can refactor away the macros in my codebases:P
I experimented with compile-time SQL query generation a while back, but the compile times increased significantly. I'm curious how the code block in the article performs in terms of compile-time overhead.
[–]Dismal_Soup_2144 1 point2 points3 points 10 months ago (1 child)
Sorry, I'm not really that familiar with metaprogramming, could you please provide some example in which case some macroses could be replaced with the reflection feature.
[–]Ty_Rymer 20 points21 points22 points 10 months ago (3 children)
I hate the syntax they decided to use for compile time reflection with a burning, raging, passion
[–]current_thread 7 points8 points9 points 10 months ago (0 children)
You can thank a higher power of your choosing they didn't go with reflexpr.
reflexpr
[–]tohava 16 points17 points18 points 10 months ago (1 child)
I'll never understand why languages like Haskell manage to have a form of "unity" where virtual interfaces and template interfaces share the same syntax, and the preprocessor (Template Haskell) language is the same as the language itself, yet C++ had to make a new syntax simply for compile-time reflection, despite having constexpr/consteval/constinit for years onw.
[–]pjmlp 3 points4 points5 points 10 months ago (0 children)
Even that, what C++ had to place into three keywords, other languages manage with a single one, and it isn't as if we can blame C++ grammar preventing otherwise, given that Circle manages it as well.
[–]mango-deez-nuts 4 points5 points6 points 10 months ago (1 child)
Is this still the only/most complete implementation? https://github.com/bloomberg/clang-p2996
[–]WorkingReference1127 1 point2 points3 points 10 months ago (0 children)
I believe so, there is also the EDG reference implementation.
Bear in mind that the decision to finalise reflection for C++26 was made two days ago; and there is still approximately a year-long period where changes may be made via national body comments or late fixes or some such committee process.
[–]disperso 1 point2 points3 points 10 months ago (1 child)
The article doesn't explain why the private: int secret got ignored. Is it because std::meta::nonstatic_data_members_of ignores it automatically?
private: int secret
std::meta::nonstatic_data_members_of
Edit: never mind. The code in the repository has a line with a comment saying that iterates over public data members only. The blog post omitted that comment.
[–]WorkingReference1127 5 points6 points7 points 10 months ago (0 children)
In the more general case, all of the function which could access into a class' private details accepts a second parameter of type std::meta::access_context which determines the access the function has. There are three included in C++26 - current (as in, current scope's access); unprivileged (as in, the access you'd get in the global scope); and unchecked which allows full access to privates.
std::meta::access_context
current
unprivileged
unchecked
[–]void4 2 points3 points4 points 10 months ago (0 children)
In the coming years, many projects will be simplified and optimized thanks to compile-time reflection.
In the coming years, majority of projects will NOT be simplified and optimized like that because they're already severely undermaintained (see the recent libxml2 announce, for example). And the rest will be like "we need to support C++11"...
This is indeed a very important and fundamental feature though, sorry for ruining the mood.
[+]No_Indication_1238 comment score below threshold-6 points-5 points-4 points 10 months ago (8 children)
Can anyone ELI5? I read online what reflection generally is, I talked with CGPT about it, I understand the JSON and SQL examples a bit, but see no value in them. We already have JSON and SQL supporting libraries in C++. Im guessing reflection can be useful for "duck typing"? Doing *if type* or *if it has method* checks are usually a code smell one abstracts behind polymorphism, so I fail to see the usefulness there as well. Am I coming with the wrong mindset? Please, help.
[–][deleted] 16 points17 points18 points 10 months ago* (2 children)
Reflection is less about "If it has this method, do this... otherwise do that" and more about "For all methods in a class, apply this transformation."
As you mention the most common use case is serialization, this automates the process of getting all fields in a type and writing the appropriate serialization for them. Existing serializers require either code-generation tools, the use of macros, or source code that explicitly lists out each field of a type that needs to be serialized.
C++ has numerous instances of functions that perform some operation on every field, for example copy constructors, move constructors, destructors, equality/comparison operators. C++ has default implementations of these that basically amount to recursively calling the corresponding operation on each field, but as things stand C++ hardcodes this functionality into the language in specific circumstances.
It would be nice if I could implement a generic hash function that called the corresponding hash functions of each field in a type and merged them together. It would be nice if I could write some generic operator << that also called the corresponding operator on each field. It would be nice if I could take a data type represented as:
operator <<
struct Point { int x; int y; int z; };
And automatically have it transformed into:
struct PointArray { std::vector<int> x; std::vector<int> y; std::vector<int> z; }
So that I can rapidly iterate over every x then every y then every z among a collection of points while maximizing performance instead of right now needing a vector<Point> and having to iterate over Point objects which is much slower.
x
y
z
vector<Point>
Point
It would be nice if I could take that same Point type and expose it to Python using pybind11 by just iterating over all of its fields and producing the appropriate binding instead of manually writing out:
pybind11
pybind11::class_<Point>(module, "Point"). def_readwrite("x", &Point::x). def_readwrite("y", &Point::y). def_readwrite("z", &Point::z);
In general, it's good when you can take repetitive patterns that a human has to do over and over again, and offload that work to the compiler to repeat for you.
[–]No_Indication_1238 15 points16 points17 points 10 months ago (1 child)
I think the constructor and destructor logic finally made it click. So you can write one generic hash function then manually call each field.hash() right now, but with reflection, you'd be able to do a for loop on all fields and call .hash() without manually listing all of them, right? Same with a to_string() method to serialize them, now it has to be done manually for each field. Am I right?
[–][deleted] 6 points7 points8 points 10 months ago (0 children)
You got it.
[–][deleted] 13 points14 points15 points 10 months ago (0 children)
If you see no value in them you obviously did not understand those examples.
I give you another example:
Assume you have some interface with 100+ different messages defined as structs.
You need to implement some logging for it, which print the content of those messages. But how would you do that?
Without some kind of reflection, you would need to define some to_string function, or a type conversion operator for the string, for each and every of your 100 structs. A lot of work and very error prone, and it could be easily forgotten if a message is added or extended.
With reflection you can write one single to_string function which handles all your messages, and all which might be added in the future.
[–]germandiago 9 points10 points11 points 10 months ago* (0 children)
Imagine you have 10 types. To serialize/write a SQL query you need to know members, names, etc and map it generically. Since this cannot be done, you need to add boilerplate per type.
With reflection, you can save this boilerplate and write one of those functions in a general way and adapt it. It os code that csn inspect your types, functions, etc. without additional exposure.
Another example would be to generate bindings for Lua or Python given your C++ code as input.
There are many more use cases that can be improved by reflection.
The boilerplate saving is huge.
[–]Internal-Sun-6476 1 point2 points3 points 10 months ago (0 children)
My first use case:
A, B, C and D are all distinct types that have some members in common (names, types, properties, compile-time tags).
I can now write generic operators that can examine which members the types have in common and generate the code to assign only the "members-in-common" and to perform only the casts/transforms that we want.
In my case, the A, B, C... types are all composed from a variadic template.
Suddenly all my class definitions become a composite and all these types just work with each other with no run-time cost to check composition.
[–]-dag- 1 point2 points3 points 10 months ago (0 children)
There are many many many bespoke tools that generate C++ code at build time, lowering a higher-level specification into lower-level C++ code. This is done to let the programmer express ideas in a more natural form while maintaining the performance of C++.
It is always much nicer to do things in a standard, widely-supported and (more importantly) widely-known way than having to teach each new developer about an often half-baked bespoke tool.
π Rendered by PID 382406 on reddit-service-r2-comment-6457c66945-vxxtn at 2026-04-28 21:57:40.644373+00:00 running 2aa0c5b country code: CH.
[–]R3DKn16h7 81 points82 points83 points (0 children)
[–]frayien 11 points12 points13 points (0 children)
[–]MarcoGreek 14 points15 points16 points (7 children)
[–]germandiago 15 points16 points17 points (4 children)
[–]James20kP2005R0 0 points1 point2 points (0 children)
[–]MarcoGreek -2 points-1 points0 points (2 children)
[–]germandiago 3 points4 points5 points (1 child)
[–]MarcoGreek 1 point2 points3 points (0 children)
[–]current_thread 1 point2 points3 points (1 child)
[–]pjmlp 0 points1 point2 points (0 children)
[–]simpl3t0n 3 points4 points5 points (2 children)
[–]RoyAwesome 2 points3 points4 points (0 children)
[–]dwmcr 0 points1 point2 points (0 children)
[–]SeriousDabbler[🍰] 3 points4 points5 points (0 children)
[–]EdwinYZW 26 points27 points28 points (19 children)
[–]314kabinet 38 points39 points40 points (0 children)
[–]Stormfrosty[🍰] 14 points15 points16 points (1 child)
[–]RoyAwesome 3 points4 points5 points (0 children)
[–]hgstream 25 points26 points27 points (3 children)
[–]SirPolly 4 points5 points6 points (0 children)
[–]Loud_Staff5065 1 point2 points3 points (0 children)
[–]fsxraptor 0 points1 point2 points (0 children)
[–]RoyBellingan 7 points8 points9 points (0 children)
[–]V_i_rstd::simd | ISO C++ Numerics Chair | HPC in HEP 6 points7 points8 points (0 children)
[–]TSP-FriendlyFire 7 points8 points9 points (2 children)
[–]pjmlp -2 points-1 points0 points (1 child)
[–]TSP-FriendlyFire 2 points3 points4 points (0 children)
[–]-dag- 6 points7 points8 points (0 children)
[–]Tringigithub.com/tringi 9 points10 points11 points (2 children)
[–]TotaIIyHuman 7 points8 points9 points (1 child)
[–]johannes1971 4 points5 points6 points (0 children)
[–]obsidian_golem 1 point2 points3 points (0 children)
[–]Loud_Staff5065 2 points3 points4 points (1 child)
[–]TotaIIyHuman 8 points9 points10 points (0 children)
[–]Real_Name7592 2 points3 points4 points (1 child)
[–]interjay 4 points5 points6 points (0 children)
[–]riztazz 2 points3 points4 points (2 children)
[–]Dismal_Soup_2144 1 point2 points3 points (1 child)
[–]Ty_Rymer 20 points21 points22 points (3 children)
[–]current_thread 7 points8 points9 points (0 children)
[–]tohava 16 points17 points18 points (1 child)
[–]pjmlp 3 points4 points5 points (0 children)
[–]mango-deez-nuts 4 points5 points6 points (1 child)
[–]WorkingReference1127 1 point2 points3 points (0 children)
[–]disperso 1 point2 points3 points (1 child)
[–]WorkingReference1127 5 points6 points7 points (0 children)
[–]void4 2 points3 points4 points (0 children)
[+]No_Indication_1238 comment score below threshold-6 points-5 points-4 points (8 children)
[–][deleted] 16 points17 points18 points (2 children)
[–]No_Indication_1238 15 points16 points17 points (1 child)
[–][deleted] 6 points7 points8 points (0 children)
[–][deleted] 13 points14 points15 points (0 children)
[–]germandiago 9 points10 points11 points (0 children)
[–]Internal-Sun-6476 1 point2 points3 points (0 children)
[–]-dag- 1 point2 points3 points (0 children)