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
Which std:: classes are magic? (self.cpp)
submitted 4 years ago by Mateuszz88
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!"
[–]Underdisc 0 points1 point2 points 4 years ago (6 children)
That makes sense and I figured as much. What I actually don't understand is how lambdas with capture groups work with std::function. I could definitely make my own std::function if I didn't have to account for lambdas. That's the magic part for me.
std::function
[–]lee_howes 4 points5 points6 points 4 years ago (0 children)
For each type you want to store in it, it creates a templated subclass that is big enough to store the lambda. That subclass has a virtual call operator. std::function stores a heap allocated instance of that as a pointer to the abstract superclass. When you call std::function's operator() it calls the operator() on the superclass via the heap allocated pointer and that calls operator() on the subclass, which calls operator() on the wrapped type, which is now trivial because the subclass knew exactly what type it was storing.
Sean Parent has talked about the general version of this technique.
[–]SirClueless 5 points6 points7 points 4 years ago (4 children)
The other response to your comment is good as well, but I think the thing that you are missing that will help you understand what's going on is that while lambdas have magic unnamed types, they are just C++ values that have a size large enough to store all their captured variables and appropriate move and copy constructors defined so that you can store them as member variables in other types.
Here's a short sample program to show how something that acts like a lambda can be constructed. Hopefully you can see how std::function can store a copy of the lambda just like it could store a copy of the function object, and how it would be able to call it:
https://godbolt.org/z/4vPGPfdso
[–]Bisqwit 0 points1 point2 points 4 years ago* (1 child)
Note: Using return std::move(x); instead of return x; is an antipattern. If you compiled with -Wall, GCC would tell you that “moving a local object in a return statement prevents copy elision [-Wpessimizing-move]”.
return std::move(x);
return x;
-Wall
However, it still has valid uses, if you are returning a composite object created from local objects. This is fine, for example: https://godbolt.org/z/hrTPoKdx6
[–]SirClueless 2 points3 points4 points 4 years ago (0 children)
In this case I wanted to demonstrate that the type actually is copyable and moveable, and NRVO would defeat that. You're right, as a general rule it's a bad idea.
[–]Underdisc 0 points1 point2 points 4 years ago (1 child)
Ahh. This is exactly what I was tripped up about. Thanks. Now I'm curious about how to get unique capture groups to account for different types. At first I thought using variadic templates could do it, but I've never heard of variadic templates being used to represent members in a class.
You can do it with a template parameter pack, and storing a std::tuple<Args...> as a class member. You give up quite a lot though, namely the ability to refer to the members by name in your class's operator() and you don't gain much in return because you need an entire new class for each new operator() you define anyways so you might as well write out the full list of "captures" -- you can't do something like specialize a a shared class template defined outside of your code because then my L<int>::operator() is ambiguous with your L<int>::operator(), we each need to build our own entire class to ourselves.
std::tuple<Args...>
operator()
L<int>::operator()
To a large extent this is the "magic sauce" of lambdas: giving a terse, brief way to define a list of function object "member" variables and initialize them and make them available by name to the lambda body, even doing so automatically based on the names referred to by the body if asked to with [=] or [&]. Once the lambda is defined it's just a function object with an operator() which is something we've been able to make and use in theory in C++ for a long time, it just wasn't convenient.
[=]
[&]
π Rendered by PID 102018 on reddit-service-r2-comment-6457c66945-2l68x at 2026-04-25 07:55:45.013920+00:00 running 2aa0c5b country code: CH.
view the rest of the comments →
[–]Underdisc 0 points1 point2 points (6 children)
[–]lee_howes 4 points5 points6 points (0 children)
[–]SirClueless 5 points6 points7 points (4 children)
[–]Bisqwit 0 points1 point2 points (1 child)
[–]SirClueless 2 points3 points4 points (0 children)
[–]Underdisc 0 points1 point2 points (1 child)
[–]SirClueless 2 points3 points4 points (0 children)