lambda question

Feb 21, 2021 at 6:04pm
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?
Feb 21, 2021 at 6:36pm
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).
Feb 21, 2021 at 6:54pm
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.
Feb 21, 2021 at 7:08pm
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.
Feb 22, 2021 at 4:51am
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.
Feb 22, 2021 at 6:22am
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.
Feb 22, 2021 at 8:47am
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 Feb 22, 2021 at 9:20am
Feb 22, 2021 at 9:30am
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

Feb 22, 2021 at 9:37am
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 Feb 22, 2021 at 6:07pm
Feb 22, 2021 at 9:49am
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....
Feb 22, 2021 at 10:08am
Feb 22, 2021 at 5:37pm
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 Feb 22, 2021 at 5:39pm
Topic archived. No new replies allowed.