I am learning about lambdas and confused about a few things i am being taught. I have read that a lambda is a functor, which I think is basically a class that has a overloaded () operator. But when i look at code using lambdas i see no classes, so do I not need to make these classes myself? Does the compilier create these classes and then create the instances of the object of the classes when a lambda is created?
In our code, we write just the lambda expression; when it is evaluated (by the compiler), the result is a closure object (object of a class that has an overloaded () operator).
You don't have to do anything other than write the lambda code. The compiler takes the lambda expression and "expands" it into an unnamed “hidden” function object type.
You can either write a named function object, or write a lambda.
I was confused about lambdas myself, and about a year ago I ran across a digital book that does a good job of showing the history of lambdas, explaining why lambdas were a good addition to the C++ standard.
C++ Lambda Story
Everything you need to know about Lambda Expressions in Modern C++!
From C++98 to C++20 https://leanpub.com/cpplambda
The author's C++17 in Detail is also something worth having in your programming library.
I prefer to make functions because I reuse the same lambdas so often ... don't know if that is me, or the nature of them, or what but the throwaway in place ones seem to be the opposite of code reuse.
Is the line auto write = []( auto a ){ cout << a << ' '; };
in the below code really legitimate? It looks almost like templates without the "template".
#include <algorithm>
#include <iostream>
#include <vector>
usingnamespace std;
int main()
{
auto write = []( auto a ){ cout << a << ' '; }; // *** Is this really legit?
auto writeall = [write]( auto A ){ for ( auto e : A ) write( e ); cout << '\n'; };
auto twice = []( int &a ){ a *= 2; };
vector<int> v = { 1, 2, 3 };
for_each( v.begin(), v.end(), write ); cout << '\n';
for_each( v.begin(), v.end(), twice );
writeall( v );
auto w = writeall;
vector<double> vv = { 0.1, 0.2, 0.3 };
w( vv ); // Crikey!
}
Watch out for the capture clauses - they can be either by ref or by value. If by value, the value used is the value at the time the lambda is defined, not used. Still got the bite mark....
Ah, you name your lambdas in those examples. I see a lot of unnamed ones, and I guess I dislike anything unnamed across the board.. enum, struct, lambda, all of it.
I need to look into making a file of commonly used named ones... thx