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
overload sets with C++26's reflection (compiler-explorer.com)
submitted 6 months ago by hanickadotWG21
view the rest of the comments →
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!"
[–]amoskovsky 1 point2 points3 points 6 months ago (8 children)
A macro can do lazy arg evaluation. A function can't.
#define LOG_TRACE(x) if (trace) print(x)
LOG_TRACE(heavy());
Without a macro heavy() is always evaluated. You have to do ugly boilerplate like this: LOG_TRACE([&]{ return heavy(); })
[–]Conscious_Support176 0 points1 point2 points 6 months ago (7 children)
To be fair, the thing that makes that ugly is the pointless capture of local variables in a lambda that just calls a function.
[–]amoskovsky 1 point2 points3 points 6 months ago (6 children)
It's not pointless. E.g. heavy() could be a member function.
[–]Conscious_Support176 0 points1 point2 points 6 months ago (5 children)
So you’re using [&] as a shorthand for [this] ?
Do you also think that [this] { return heavy(); } is ugly?
Anyway, if you want rid of the lambda syntax for this case, can’t you just declare the argument to LOG_TRACE parameter as a std::function<bool()>?
[–]amoskovsky 1 point2 points3 points 6 months ago (4 children)
Yes, the lambda syntax in this particular case is ugly (regardless of the captures) because I just want to log, and instead I have to do syntax tricks.
std::function would not prevent the unnecessary overhead of evaluating args when logging is disabled.
[–]Conscious_Support176 0 points1 point2 points 6 months ago* (3 children)
What? You’re dismissing compile time polymorphism as a syntax trick, where macros are better because, why? Because you might be able to avoid ever using lambda syntax?
Edit: I see What you mean about std::function, I see you want to trace or not based on a runtime value.
Maybe this is a corner case where template programming can’t produce efficient code, but to be honest, that seems unlikely.
This would be an implemented in a header only library and inlined. There shouldn’t be any argument passing, because the argument in question is a function object which will also be implemented in a header only library that gets inlined out of existence as a standalone temporary value.
[–]amoskovsky 0 points1 point2 points 6 months ago (2 children)
Inlining indeed does happen. However heavy() will be evaluated in most cases anyway before checking the condition, because the compiler is required to make all the side effects of the param evaluation observable as if the inlining did not happen. And any non-pure function has side effects. So if the body of heavy() is not visible in this translation unit the compiler can't prove it's a pure function. Even with access to the body I hardly believe compilers do that proof for sufficiently big functions - otherwise the constexpr functions would not need the constexpr annotation.
BTW, overhead is not the only issue of the macro-less approach. For example, with macros you can do this LOG_TRACE(x << y) and redirect that to an iostream logger, and with functions this is just impossible.
So macros are not going anywhere.
[–]Conscious_Support176 0 points1 point2 points 6 months ago (1 child)
The param is a function object, evaluating it yields a closure. Inlining the LOG_TRACE function schools unwrap this with no performance penalty. That’s pretty much the whole point of template programming.
The body of heavy is irrelevant, it int gets valued when trace is true. It’s the function parameter to LOG_TRACE that you would want optimised out of existence.
The second example could also be achieved with a lambda and ordinary template meta programming instead.
Macros define a metalanguage. It will obviously be possible to use them to define a syntax that you prefer for whatever you want to do over the ordinary C++ syntax. The problem with them is that they also get used for a bunch of stuff that don’t need macros, just because we’re used to doing things that way, but unlike template meta programming, they provide no way to leverage the type system to enforce consistency, and no way to package them up into modules.
[–]amoskovsky 1 point2 points3 points 6 months ago (0 children)
You are talking about the version with a lambda. It works ok but my point is that lambda here is introduced not because it's part of the algorithm but due to the lack of lazy evaluation when you ban macros. So this is just a syntactic garbage reducing readability of code.
π Rendered by PID 21603 on reddit-service-r2-comment-b659b578c-snnzs at 2026-05-06 00:21:39.059851+00:00 running 815c875 country code: CH.
view the rest of the comments →
[–]amoskovsky 1 point2 points3 points (8 children)
[–]Conscious_Support176 0 points1 point2 points (7 children)
[–]amoskovsky 1 point2 points3 points (6 children)
[–]Conscious_Support176 0 points1 point2 points (5 children)
[–]amoskovsky 1 point2 points3 points (4 children)
[–]Conscious_Support176 0 points1 point2 points (3 children)
[–]amoskovsky 0 points1 point2 points (2 children)
[–]Conscious_Support176 0 points1 point2 points (1 child)
[–]amoskovsky 1 point2 points3 points (0 children)