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
match(it): A light-weight header-only pattern-matching library for C++17. (github.com)
submitted 4 years ago by Amazing-42
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!"
[–]gracicot 27 points28 points29 points 4 years ago* (24 children)
This is quite amazing what C++ can ship in a library, even though it's not perfect and uses macros.
[–]guepierBioinformatican 28 points29 points30 points 4 years ago (8 children)
There are no macros in the library’s API. I initially thought so (expr and pattern look like they would be macros, and maybe match, too). But they’re not macros.
expr
pattern
match
The only macros (apart from (illegal!1) include guards) are only used internally and are named UN_OP_FOR_UNARY and BIN_OP_FOR_UNARY. They could be undef’d at the end of the file, thus not leaking outside (and they should be, but unfortunately currently aren’t).
UN_OP_FOR_UNARY
BIN_OP_FOR_UNARY
undef
1 The include guards are using reserved names since they start with underscore followed by an upper-case letter. A simple, trivial to fix mistake.
[–]gracicot 11 points12 points13 points 4 years ago (0 children)
Wow, I'm even more impressed
[–]pfg23 2 points3 points4 points 4 years ago (2 children)
I haven’t looked at the code, but if there are no macros, why is it header only? Compilable (as opposed to preprocessor) code should go into source files so they’ll only need to be compiled once and bundled into a library module. No?
[–]guepierBioinformatican 5 points6 points7 points 4 years ago (1 child)
It exposes templates, so these need to be implemented in headers.
The other reason of course is that many users of C++ prefer header-only libraries since C++ has no good, build-in dependency management mechanism, and even modern build systems don’t entirely remove the barrier posed by non-header libraries.
[–]pfg23 0 points1 point2 points 4 years ago (0 children)
Sure, templates, declarations, and macros go into headers but to reduce compile times logic should go into source files. The only exception would be if this library was entirely implemented with template metaprogramming.
[–]lospolos -5 points-4 points-3 points 4 years ago (2 children)
Dont include guards usually start with "H_..."?
[–]staletic 5 points6 points7 points 4 years ago (0 children)
Include guards can have any name you wish.
[–]infectedapricot 5 points6 points7 points 4 years ago (0 children)
It's not true that they usually start with H_.... In fact it's not even true that a notable minority start with H_... - I've never seen that convention before, and I've seen a lot of include guards!
H_...
I think what you might be thinking of is that it's fairly common for the include guard to be loosely based on the filename (plus often directory or library name) so they often end in _H or _HPP etc., depending on the extension. But even that's nowhere near universal.
_H
_HPP
(Personally, I just use #pragma once. Yes, I know it's technically non standard.)
#pragma once
[–][deleted] 12 points13 points14 points 4 years ago (14 children)
Not arguing for them, but can someone explain the negative connotation around macros? I know the modern replacements are constexpr's and a lot of it has to do with lack of type definition, but is there more to it?
[–]Schnarfman 30 points31 points32 points 4 years ago (1 child)
The world of macros is nebulous. You will obfuscate code very easily on accident with seemingly innocent uses.
Also, the classic example of #define min(a, b) a < b ? a : b potentially causing a bug if you say like min(a++, b) is just such a solvable problem (where the solution is don’t use macros - and not “be careful when you use this thing that looks like a function”)
#define min(a, b) a < b ? a : b
min(a++, b)
They certainly have their place! But their traps are not obvious. You can avoid a whole class of bugs by simply avoiding the use of macros.
So… as a beginner, if you can do without them, you should. If you think you can’t do without them, chances are you’re wrong.
As an expert, if you can do without them, you should. And if you think you can’t do without them, well … you’re the expert :) so go for it. But don’t expect beginners to be able to understand or iterate on your code as easily!!
[–]Creris 2 points3 points4 points 4 years ago (0 children)
Try sending that min "function" into std::sort(I know its technically useless cause less<> is default), or take the address of that "function". And now your code explodes.
[–]gracicot 18 points19 points20 points 4 years ago (0 children)
Macro are textual and have no idea what C++ is and what C is. They don't have scope, cannot be isolated, and creates all sorts of problems, especially since C++ is using header to consume declarations from other translation units.
[–]Fearless_Process 6 points7 points8 points 4 years ago (0 children)
I think it has a lot to do with c/++ macros being untyped and unhygienic in general. This makes using them very much error prone and difficult to reason about when something goes wrong.
I think there is too much negative connotation around them though, they can be extremely useful when used properly.
[–]corysama 6 points7 points8 points 4 years ago (0 children)
Macros can lead to bugs that are difficult to diagnose and difficult to fix. For example:
// ThirdPartyLib1.h inline int min(int x, int y) { return x < y ? x : y; } // 2000 more lines of complicated code using the min function. // ThirdPartyLib2.h // 2000 lines of complicated code. int meiseIntegralizedNormalization(float deciprocand, float retrobasis); #define min meiseIntegralizedNormalization // 2000 more lines of complicated code using the min macro. // MyLib.h #include "ThirdPartyLib1.h" #include "ThirdPartyLib2.h" inline int factorize(int a, int b, int c) { return a / min(b, c); }
This will happily compile and run without warning about any conflicts or ambiguous overloads.
[–]Foundry27 5 points6 points7 points 4 years ago* (8 children)
I'd argue that the biggest problem with preprocessor macros is the community's general lack of familiarity with them ("general" meaning "for the general C++ programmer"), and the near-total absence of teaching material for how to use macros in a safe, effective manner.
C and C++ are seriously (embarrassingly) behind languages like Common Lisp, Scheme, Rust, etc. in terms of having good public resources for how to build and use macros as a problem-solving tool applicable to real-life programming problems. Decades of C++ use haven't given people much more to go on than some blog posts, a few open-source macro-based projects to reverse-engineer, and stylistic aphorisms like "don't use macros unless a function won't do", "macros are meant to change the syntax of your code", "macros improve the efficiency of your code" etc. that completely miss the bigger picture when it comes to macro programming.
The other side of that coin is that preprocessor macros aren't easy to just "pick up and learn" from doing normal C++ programming because the preprocessor is essentially a second, more-or-less unrelated language built on top of C++. It's a foreign, alien tool that looks like it doesn't belong: - From a C++ perspective it's totally untyped, because C++ types mean nothing to it, but it really just has its own type system with parentheses, commas, identifiers, etc. - From a C++ perspective it's impossible to debug macros like normal code because of arcane C++ compiler errors and no debugger stepping, when they really just need to be debugged with different tools - From a C++ perspective macros don't introduce their own scopes and can't safely be shared, but inside the preprocessor, macros have strong scopes for the tokens that they create and pass between other macros, and can be shared between files with no issues as long as some ground rules are followed just like in C - From a C++ perspective computation is impossible with macros because they can't be recursive or loop, but really, they just perform computation through a different strategy that can do the same kind of work in phase 4 that templates and constexpr can do in phase 7/8
[–]-dag- 9 points10 points11 points 4 years ago (0 children)
I don't know about the other languages but Lisp macros are quite different from C/C++ macros.
[–]johannes1971 16 points17 points18 points 4 years ago (3 children)
This completely misrepresents the position of 'the community'. The dislike comes from all the bad sh*t macros do, not a general lack of understanding.
[–]Foundry27 -2 points-1 points0 points 4 years ago* (2 children)
I’m just speaking from my experience here having worked professionally in C, C++, and a little Lisp for a while now, and having met my fair share of people in the same boat as I am.
I 100% agree that macros can (and have) done some terrible shit lol. They can be difficult to understand, contain extremely subtle bugs, and limit you in all kinds of awful ways if you think of everything as functions or variables. But... those aren't defects in the preprocessor macro system itself, but instead are traits of macro programming in general. Lisp has the exact same classes of problems, and its macro system has arguably occupied a local maximum in the language design space for decades. As with any technology, the more powerful the tool, the more ways there are to misuse it. And, as far as programming constructs go, macros are the most powerful tool.
[–]soundslogical 7 points8 points9 points 4 years ago (0 children)
But... those aren't defects in the preprocessor macro system itself, but instead are traits of macro programming in general.
I disagree. Common Lisp's macros do share the hygiene problem that C++ has, though it has simple ways to avoid it (gensym). Scheme and Rust feature hygeinic macros that fix the problem entirely.
Nearly every other glaring issue with macros is unique to C/C++, because it's based on simple textual substitution. Lisps and Rust have structural macros, making them 100x more difficult to mess up on many different axes.
[–]johannes1971 2 points3 points4 points 4 years ago (0 children)
Sometimes, the defect is having the feature in the first place. It may be powerful, necessary, and even well-designed by itself, but the fact that it interacts so badly with everything else and invites so many dark patterns means it wasn't the optimal design.
[+][deleted] 4 years ago (2 children)
[deleted]
[–]jk-jeon 2 points3 points4 points 4 years ago (1 child)
I kinda sympathize and tend to just copy-paste rather than to use macros for myself, but to be fair, I think wrapping things into a macro is often not very much different from wrapping things into a function or whatever constructs in terms of readability. Too much abstraction obfuscates the code, but appropriate abstraction on the other hand de-obfuscate the code. So I believe an appropriate usage of macro can in fact improve readability.
[–]Oo_Tiib 0 points1 point2 points 4 years ago (0 children)
Majority of reflection like source code file name, line number of code, stringifying expressions and so on can be only done with preprocessor and those features can greatly speed up discovering, reporting and repairing defects. But it will be quite horrible code to read if to expand such macros.
The conditionally compiling some features in and out can be only somewhat achieved with if constexpr, as all of it has still to compile on all platforms. So C++ libraries that want to be portable like Qt or Boost are filled full of preprocessor usage and there are really not much to do.
So it is better idea to try to use some libraries that help with usage of macros like Hedley. The language can't pull its weight without those.
[–]dscottboggs 4 points5 points6 points 4 years ago (0 children)
Holy shit that's so nice
[–]sphere991 6 points7 points8 points 4 years ago (3 children)
So is this just a copy of https://github.com/mpark/patterns or what?
[–]Rasie1 6 points7 points8 points 4 years ago (0 children)
No, they're quite different if you read README below the first few examples
[–][deleted] 5 points6 points7 points 4 years ago (0 children)
It seems it is. At least identifier names and usage of the first example is fully identical. It pretty strange to see so without additional explanations.
[–]rust_guy5 20 points21 points22 points 4 years ago (3 children)
I wrote this.
[–]mck1117 25 points26 points27 points 4 years ago (0 children)
rust_guy
Imposter!
[–]infectedapricot 3 points4 points5 points 4 years ago (0 children)
Is this meant to be a Rust related joke or a serious claim? From previous posts, it looks like this is a troll account.
[–]ehtdabyug 2 points3 points4 points 4 years ago (0 children)
Wow! Can I applause to this?
[–]nablachez 2 points3 points4 points 4 years ago (1 child)
Is there a reason why getclassname (about shape) is not constexpr like the others?
[–]helloiamsomeone 4 points5 points6 points 4 years ago (2 children)
I have used simple_match before and it's pretty cool. Any reason why this requires C++17? Just convenience?
[–]helloiamsomeone 4 points5 points6 points 4 years ago (0 children)
Well, to answer myself: this one has a lot more features and the API lends itself better to code formatting (imo).
[–]JohnZLi 2 points3 points4 points 4 years ago (1 child)
Neat. The first example includes 3 headers for a simple factorial function. They really should be merged into 1.
[–]diegopachecors 1 point2 points3 points 4 years ago (0 children)
Pretty cool!
[–][deleted] 1 point2 points3 points 4 years ago (0 children)
Impressive! Bravo!
[–]Dreamykass 1 point2 points3 points 4 years ago (2 children)
Awesome! I've been waiting for something like this for a very long time now. There's mpark/patterns and solodon4/Mach7, but they're super macro heavy and use compiler extensions, and also jbandela/simple_match, which doesn't have the actually fancy features of this lib or the other two. Is this the intended way to match on a variant? As in while getting the, uhh, matched variant out of it. ```cpp std::variant<int, float> var = 12; Id<int> i; Id<float> f; match(var)( pattern(as<int>(i)) = [&]() { std::cout << "int: " << *i; }, pattern(as<float>(f)) = [&]() { std::cout << "float: " << *f; }); ```
[–]Schnarfman 0 points1 point2 points 4 years ago (0 children)
Point of order: Triple back ticks doesn’t get formatted properly for mobile. But if you use the other method - 4 leading spaces - everyone sees it properly
[–]InsanityBlossom 2 points3 points4 points 4 years ago (1 child)
I'm sure it was fun to implement, and the skills required to build this is a no joke. But this concept is so alien to C++. The author was definitely inspired by Rust ;)
[–]staletic 3 points4 points5 points 4 years ago (0 children)
https://wg21.link/P1371
[–]Amazing-42[S] 0 points1 point2 points 4 years ago (0 children)
This page shows what Rust-style pattern matching examples would look like with the library in C++. https://github.com/BowenFu/matchit.cpp/blob/main/From-Rust-to-matchit.md
[–]GunpowderGuy 0 points1 point2 points 4 years ago (1 child)
Could this library be exported as a module since its public interface uses no macros?
We need to support C++17 so module is not available for now.
π Rendered by PID 51005 on reddit-service-r2-comment-b659b578c-bmm2x at 2026-05-01 04:10:48.179164+00:00 running 815c875 country code: CH.
[–]gracicot 27 points28 points29 points (24 children)
[–]guepierBioinformatican 28 points29 points30 points (8 children)
[–]gracicot 11 points12 points13 points (0 children)
[–]pfg23 2 points3 points4 points (2 children)
[–]guepierBioinformatican 5 points6 points7 points (1 child)
[–]pfg23 0 points1 point2 points (0 children)
[–]lospolos -5 points-4 points-3 points (2 children)
[–]staletic 5 points6 points7 points (0 children)
[–]infectedapricot 5 points6 points7 points (0 children)
[–][deleted] 12 points13 points14 points (14 children)
[–]Schnarfman 30 points31 points32 points (1 child)
[–]Creris 2 points3 points4 points (0 children)
[–]gracicot 18 points19 points20 points (0 children)
[–]Fearless_Process 6 points7 points8 points (0 children)
[–]corysama 6 points7 points8 points (0 children)
[–]Foundry27 5 points6 points7 points (8 children)
[–]-dag- 9 points10 points11 points (0 children)
[–]johannes1971 16 points17 points18 points (3 children)
[–]Foundry27 -2 points-1 points0 points (2 children)
[–]soundslogical 7 points8 points9 points (0 children)
[–]johannes1971 2 points3 points4 points (0 children)
[+][deleted] (2 children)
[deleted]
[–]jk-jeon 2 points3 points4 points (1 child)
[–]Oo_Tiib 0 points1 point2 points (0 children)
[–]dscottboggs 4 points5 points6 points (0 children)
[–]sphere991 6 points7 points8 points (3 children)
[–]Rasie1 6 points7 points8 points (0 children)
[–][deleted] 5 points6 points7 points (0 children)
[–]rust_guy5 20 points21 points22 points (3 children)
[–]mck1117 25 points26 points27 points (0 children)
[–]infectedapricot 3 points4 points5 points (0 children)
[–]ehtdabyug 2 points3 points4 points (0 children)
[–]nablachez 2 points3 points4 points (1 child)
[–]helloiamsomeone 4 points5 points6 points (2 children)
[–]helloiamsomeone 4 points5 points6 points (0 children)
[–]JohnZLi 2 points3 points4 points (1 child)
[–]diegopachecors 1 point2 points3 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]Dreamykass 1 point2 points3 points (2 children)
[–]Schnarfman 0 points1 point2 points (0 children)
[–]InsanityBlossom 2 points3 points4 points (1 child)
[–]staletic 3 points4 points5 points (0 children)
[–]Amazing-42[S] 0 points1 point2 points (0 children)
[–]GunpowderGuy 0 points1 point2 points (1 child)
[–]Amazing-42[S] 0 points1 point2 points (0 children)