lambda question

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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
   struct
   {
      void operator()(int x) const { std::cout << x << ' '; }
   } someInstance;

   const std::vector<int> v { 1, 2, 3 };

   std::for_each(v.cbegin(), v.cend(), someInstance);

   std::cout << "\n\n";

   std::for_each(v.cbegin(), v.cend(), [] (int x) { std::cout << x << ' '; });

   std::cout << '\n';
}


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.
Thank you both for clearing that up for me. And thank you for the book recommendations, I will get a copy of it/ them to understand better.
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.
closure objects are reusable objects; they are copy and move constructible.
C++20: if there are no captures, they are also copy and move assignable.
Is the line
auto write = []( auto a ){ cout << a << ' '; };
in the below code really legitimate? It looks almost like templates without the "template".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <algorithm>
#include <iostream>
#include <vector>
using namespace 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!
}
Last edited on
A generic lambda with a parameter pack:

1
2
3
4
5
6
7
8
#include <iostream>

int main()
{
    const auto plus = [] ( auto&&... args ) { return ( ... + args ) ; } ;

    std::cout << plus( 12, 34.56, 89ULL ) << '\n' ; // 135.56
}

http://coliru.stacked-crooked.com/a/6650b8916ad8755e

These lambdas are almost a new programming paradigm!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

auto print = []( auto A, string sep=" ", string end="\n" ){ for ( auto e : A ) cout << e << sep; cout << end; };

int main()
{
   auto twice = []( auto &a ){ a *= 2; };
   
   vector<int> v = { 1, 2, 3 };
   print( v, " - ", "####\n" );
   for_each( v.begin(), v.end(), twice );
   print( v );

   auto printAgain = print;
   vector<double> vv = { 0.1, 0.2, 0.3 };
   print( vv );
   for_each( vv.begin(), vv.end(), twice );
   printAgain( vv );
}


1 - 2 - 3 - ####
2 4 6 
0.1 0.2 0.3 
0.2 0.4 0.6


Last edited on
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
Last edited on
Topic archived. No new replies allowed.