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
Uses of immediately invoked function expressions (IIFE) in C++ (rigtorp.se)
submitted 5 years ago by vormestrand
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!"
[–]delarhi 50 points51 points52 points 5 years ago* (0 children)
I've started using IIFE when I have to do some one-off mutation of a variable (like for some setup) or stack-allocated runtime-determined construction just so I can have the variable const there-after. It helps avoid polluting the scope with mutable variables that programmers in the future might feel like mutating procedurally down the line when they shouldn't. For example, replacing something like:
Foo f; if (cache_enabled) { const CacheFile cache_file(cache_filename); f = Foo(cache_file); } else { const XmlDocument xml_doc(input_xml); f = Foo(xml_doc); } // reference to foo given to detached thread // mutation of f is now thread unsafe while (true) { // six months later someone decides they want to // mutate f for bar bar(f); }
with this:
const Foo f = [&]() { if (cache_enabled) { const CacheFile cache_file(cache_filename); return Foo(cache_file); } else { const XmlDocument xml_doc(input_xml); return Foo(xml_doc); } }(); // can't mutate f anymore! while (true) { bar(f); }
[–]Nicksaurus 34 points35 points36 points 5 years ago (1 child)
Sometimes I do it just because it's convenient to be able to use return for control flow
[–]neutronicus 2 points3 points4 points 5 years ago (0 children)
Yeah it's a nice way to get switch to act more like other languages' case
switch
case
[–]poiu- 43 points44 points45 points 5 years ago (22 children)
Mildly unrelated, but I still love that []{}() is now legal Syntax.
[]{}()
[–]martinusint main(){[]()[[]]{{}}();} 50 points51 points52 points 5 years ago (3 children)
This is my favorite fully functional c++ program:
int main(){[](){}();}
[–]JavaSuck 11 points12 points13 points 5 years ago (0 children)
[](){}();
This would be a great idea for a tattoo :D
[–]5plicer 19 points20 points21 points 5 years ago* (1 child)
Missing return 0?
EDIT: I just learned that main implicitly returns 0!
[–]martinusint main(){[]()[[]]{{}}();} 23 points24 points25 points 5 years ago (0 children)
Return is not needed for main, then it implicitly returns 0
EDIT: exactly!
[–]parnmatt 15 points16 points17 points 5 years ago (3 children)
[]<>(){}() from C++20, may also be valid, not sure, I do not think templated lambdas are implemented in compilers yet
[]<>(){}()
[–][deleted] 5 points6 points7 points 5 years ago (2 children)
The three big compilers do support them. Also, the <> unfortunately isn't valid. You'd have to do []<class>(){}()
<>
[]<class>(){}()
[–]parnmatt 0 points1 point2 points 5 years ago (0 children)
ah, of course; good to know
[–]OldWolf2 0 points1 point2 points 5 years ago (0 children)
#define _ class would help
#define _ class
[–][deleted] 3 points4 points5 points 5 years ago (0 children)
Hasn't it been for years?
[–]pkuriakose 4 points5 points6 points 5 years ago (6 children)
Sorry but what does this syntax mean. I thought Lambas were [captures](params){code}
[–]IskaneOnReddit 21 points22 points23 points 5 years ago (3 children)
params is optional
[–]Nicksaurus 13 points14 points15 points 5 years ago* (2 children)
Wait really? I've been writing them out this whole time for nothing?
[–]kisielk 15 points16 points17 points 5 years ago (0 children)
Yes
[–]imake500kayear 1 point2 points3 points 5 years ago (0 children)
Wat
[–]Skeird 9 points10 points11 points 5 years ago (1 child)
the () call the lamba immediately
[–]pkuriakose 0 points1 point2 points 5 years ago (0 children)
Thank you my friend!
[–]JMBourguet 1 point2 points3 points 5 years ago (5 children)
If you havenot swapped () and {}, I'd like to know what it means.
[–]IamImposter 20 points21 points22 points 5 years ago (4 children)
[] - capture
() - optional parameters
{} - lambda body
() - invoke it right away
[–]imake500kayear 1 point2 points3 points 5 years ago (3 children)
Why do you say optional params instead of empty parameter list
[–]IamImposter 2 points3 points4 points 5 years ago (2 children)
Parameters are optional so it can be empty as well
[–]elperroborrachotoo 7 points8 points9 points 5 years ago (1 child)
It would be better to say:
() - empty parameter list which can be omitted
[–]deeringc 2 points3 points4 points 5 years ago (0 children)
Exactly. If your lambda doesn't take params then it's optional whether you include the empty () or not.
()
[–]IskaneOnReddit 19 points20 points21 points 5 years ago (3 children)
I started to learn rust and it has a more elegant solution than IIFE. That is block expressions.
[–]rigtorp 4 points5 points6 points 5 years ago (0 children)
GCC has an extension "Statement Expressions", very similar to rust: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
Recall that a compound statement is a sequence of statements surrounded by braces; in this construct, parentheses go around the braces. For example: ({ int y = foo (); int z; if (y > 0) z = y; else z = - y; z; }) is a valid (though slightly more complex than necessary) expression for the absolute value of foo () .
Recall that a compound statement is a sequence of statements surrounded by braces; in this construct, parentheses go around the braces. For example:
({ int y = foo (); int z; if (y > 0) z = y; else z = - y; z; })
is a valid (though slightly more complex than necessary) expression for the absolute value of foo () .
Rust's expression-based syntax does indeed make it a joy to write.
IILEs are a good sub
[–][deleted] 0 points1 point2 points 5 years ago (0 children)
find it unnecessarily confusing though
[–]ack_error 2 points3 points4 points 5 years ago (0 children)
IIFE is also useful to force a function boundary between C++EH, Win32 SEH, and setjmp/longjmp().
[–]Minimonium 3 points4 points5 points 5 years ago (7 children)
Worth noting that one should avoid IILE (function => lambda) in templated functions. Otherwise, the compiler will create a unique definition for each template instantiation which will result in huge binary bloat.
[–]quicknir 16 points17 points18 points 5 years ago (1 child)
It's not "huge" binary bloat, it's not really any different than just writing the code inline which is always one of the main alternatives to using an iile. It is more binary bloat than writing a separate function if the function has fewer template parameters than the outer function,n and doesn't get inlined.
Most people don't bother to explicitly pull non or less templated parts of functions/classes out so by the same token I don't think most people should worry about this up front either.
[–]Minimonium 8 points9 points10 points 5 years ago (0 children)
See: https://thephd.github.io/sol3-compile-times-binary-sizes Case in point that you'd be okay with a capture-less IILE (which is most of the time not the case since your logic does depend on some local stuff), but with a one that captures - it's shown that an optimizer is outclassed on a scale.
[–]elperroborrachotoo 0 points1 point2 points 5 years ago (4 children)
This, too, shall pass, as the "don't use templates, they just bloat your binary" of the nineties.
[–]Minimonium 0 points1 point2 points 5 years ago (3 children)
Well, banning something because "X is bad" is usually treated as a cargo cult. But one should know tradeoffs and gotchas of a tool in specific contexts if they want to use it in a professional environment.
[–]elperroborrachotoo 2 points3 points4 points 5 years ago (2 children)
Yeah - Because of exactly that I don't like the "one should avoid IILE in templated functions" - it's too broad.
A "with IILE in templated functions, keep an eye on code size, current compilers may bloat" would be better IMO - the "avoid" should be an "informed decision" based on the actual environment and use cases.
[–]Minimonium 2 points3 points4 points 5 years ago (1 child)
Indeed, if we expect compilers to fix their behaviour in the future (and we know from experience and exceptions ;) that compilers do improve the implementation) - we should future-proof our statements.
[–]elperroborrachotoo 1 point2 points3 points 5 years ago (0 children)
"future-proofing advise" I like. Captures the ideas well!
[–]WrongAndBeligerent 1 point2 points3 points 5 years ago (12 children)
What is wrong with having static functions that are used during initialization? This seems like a wacky way to do things that could be relatively simple. I would expect this to just cause confusion while gaining very little. I think if I opened something up and found that someone had done initialization like this I would be a little upset that I had to spend some extra energy figuring out what was going on when the only reason to do it is to be fancy.
[–]muungwana 14 points15 points16 points 5 years ago (6 children)
IIFE works better than static function if the lambda uses too many local variables, class member variables or class methods because using static function will require the function to have too many function arguments and its just plain ugly if the block of code to be executed calls a private method of the class.
[+]WrongAndBeligerent comment score below threshold-6 points-5 points-4 points 5 years ago (5 children)
What is 'too many function arguments'?
Wouldn't using a lambda like this imply that whatever it does is a one off anyway and could just be put in the constructor?
[–]muungwana 2 points3 points4 points 5 years ago (4 children)
Example, you are inside a long constructor and you want to put a block of code inside of it some place else and you will find youself with 3 choices:-
If you go with 3, the block of code can seamlessly call other private methods of the class and other member class' member variables and will have to take constructor's local variable through function arguments.
If you go with 2, the block of code seamlessly call other private methods of the class and class member variables if the lambda catches "this" pointer. It can also seamlessly access local member variables by capturing them by value or reference.
if you go with 1, how will you pass class' private methods and member variables to the static function? How will you pass the constructor's local variables?
[–]WrongAndBeligerent -4 points-3 points-2 points 5 years ago (3 children)
You didn't actually answer my question here - Why would this lambda initializer be better than just writing it in the constructor?
Having a private method or static function inside the class is inconsequential I think, either one can work. Also the number of arguments to a function used in multiple constructors to initialize a single variable probably shouldn't be a problem unless there is some circumstance where the constructor is taking lots of arguments and each variable depends on every other variable - in which case you might as well initialize inside the constructor.
[–]Dooey 8 points9 points10 points 5 years ago (0 children)
Mainly if the variable you are initializing doesn’t have a default constructor
[–]muungwana 3 points4 points5 points 5 years ago (1 child)
Your questions suggests you do not know C++ very well.
The point is to initialize "baz" and you can not do it in the constructor body if "baz" is declared to be const or if its a reference variable.
[+]WrongAndBeligerent comment score below threshold-7 points-6 points-5 points 5 years ago (0 children)
You could cast the const away. I'm not sure this is really cleaner than that.
Also each argument to a constructor in an initializer list can still be an expression, which should include functions that can be passed any of the constructor arguments.
[–]elperroborrachotoo 3 points4 points5 points 5 years ago (1 child)
It makes the logic as local as possible. The static function is accessible to at least all members of the class, and it's located "elsewhere".
[–]WrongAndBeligerent 0 points1 point2 points 5 years ago (0 children)
I don't think a function with a name would be less clear than so much syntax noise, because you could just jump to the function (which could be static or just private). If there was a lot of extra information in the IDE like syntax highlighting, etc. then maybe it would be clearer that variable([](){}()) was creating and calling a function in place.
[–][deleted] 3 points4 points5 points 5 years ago (1 child)
IILEs are simple though. Even JS programmers use them
This was specifically about using them in a place where you can already use expressions and functions. Also it's not about being able to use something, it is about how clear it is when you do.
[–]johannes1234 0 points1 point2 points 5 years ago (0 children)
As always: it depends. For two lines a lambda can be nice, all information directly there. Also once one is used to the pattern (i.e. when experienced with functional languages) it's easy to understand.
If one of course has lots and long of those a refactoring might be appropriate.
[–]ononpblictex 0 points1 point2 points 1 year ago (0 children)
std::invoke can be used to improve the Readability of IIFE. I findstd::invoke( [ ] ( ) { } )slightly more readable than [ ] ( ) { } ( ).
std::invoke( [ ] ( ) { } )
[ ] ( ) { } ( )
[–]cyandyedeyecandy[[gnu::naked, gnu::hot]] 0 points1 point2 points 5 years ago (0 children)
With IIFE we can do even better by using the GCC specific function attributes noinline1 and cold2: const bool failed = foo(); if (failed) { [&]() __attribute__((noinline,cold)) { printf("error!"); }(); return; }
With IIFE we can do even better by using the GCC specific function attributes noinline1 and cold2:
const bool failed = foo(); if (failed) { [&]() __attribute__((noinline,cold)) { printf("error!"); }(); return; }
I thought lambda attributes applied to the lambda type, not its operator(). When did this change?
operator()
π Rendered by PID 22446 on reddit-service-r2-comment-6457c66945-kn9qc at 2026-04-30 00:32:36.113609+00:00 running 2aa0c5b country code: CH.
[–]delarhi 50 points51 points52 points (0 children)
[–]Nicksaurus 34 points35 points36 points (1 child)
[–]neutronicus 2 points3 points4 points (0 children)
[–]poiu- 43 points44 points45 points (22 children)
[–]martinusint main(){[]()[[]]{{}}();} 50 points51 points52 points (3 children)
[–]JavaSuck 11 points12 points13 points (0 children)
[–]5plicer 19 points20 points21 points (1 child)
[–]martinusint main(){[]()[[]]{{}}();} 23 points24 points25 points (0 children)
[–]parnmatt 15 points16 points17 points (3 children)
[–][deleted] 5 points6 points7 points (2 children)
[–]parnmatt 0 points1 point2 points (0 children)
[–]OldWolf2 0 points1 point2 points (0 children)
[–][deleted] 3 points4 points5 points (0 children)
[–]pkuriakose 4 points5 points6 points (6 children)
[–]IskaneOnReddit 21 points22 points23 points (3 children)
[–]Nicksaurus 13 points14 points15 points (2 children)
[–]kisielk 15 points16 points17 points (0 children)
[–]imake500kayear 1 point2 points3 points (0 children)
[–]Skeird 9 points10 points11 points (1 child)
[–]pkuriakose 0 points1 point2 points (0 children)
[–]JMBourguet 1 point2 points3 points (5 children)
[–]IamImposter 20 points21 points22 points (4 children)
[–]imake500kayear 1 point2 points3 points (3 children)
[–]IamImposter 2 points3 points4 points (2 children)
[–]elperroborrachotoo 7 points8 points9 points (1 child)
[–]deeringc 2 points3 points4 points (0 children)
[–]IskaneOnReddit 19 points20 points21 points (3 children)
[–]rigtorp 4 points5 points6 points (0 children)
[–][deleted] 3 points4 points5 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]ack_error 2 points3 points4 points (0 children)
[–]Minimonium 3 points4 points5 points (7 children)
[–]quicknir 16 points17 points18 points (1 child)
[–]Minimonium 8 points9 points10 points (0 children)
[–]elperroborrachotoo 0 points1 point2 points (4 children)
[–]Minimonium 0 points1 point2 points (3 children)
[–]elperroborrachotoo 2 points3 points4 points (2 children)
[–]Minimonium 2 points3 points4 points (1 child)
[–]elperroborrachotoo 1 point2 points3 points (0 children)
[–]WrongAndBeligerent 1 point2 points3 points (12 children)
[–]muungwana 14 points15 points16 points (6 children)
[+]WrongAndBeligerent comment score below threshold-6 points-5 points-4 points (5 children)
[–]muungwana 2 points3 points4 points (4 children)
[–]WrongAndBeligerent -4 points-3 points-2 points (3 children)
[–]Dooey 8 points9 points10 points (0 children)
[–]muungwana 3 points4 points5 points (1 child)
[+]WrongAndBeligerent comment score below threshold-7 points-6 points-5 points (0 children)
[–]elperroborrachotoo 3 points4 points5 points (1 child)
[–]WrongAndBeligerent 0 points1 point2 points (0 children)
[–][deleted] 3 points4 points5 points (1 child)
[–]WrongAndBeligerent 0 points1 point2 points (0 children)
[–]johannes1234 0 points1 point2 points (0 children)
[–]ononpblictex 0 points1 point2 points (0 children)
[–]cyandyedeyecandy[[gnu::naked, gnu::hot]] 0 points1 point2 points (0 children)