Let's start off simple - without lambdas. Suppose we have a vector allocated for 100 floats, and we want to fill it up with random numbers in [0,1). The most obvious way is to use a looping construct of some kind.
vector<float> vec(100);
for (unsigned int i = 0; i < 100; i++)
{
vec[i] = static_cast<float>(rand()) / (static_cast<float>(RAND_MAX) + 1.0f);
}
Okay, I realize I didn't need that many casts, but I like being safe. ;) While this code does the job, we can also use std::generate() to avoid the explicit loop construct:
float randval()
{
return rand() / (RAND_MAX + 1.0f);
}
vector<float> vec(100);
generate(vec.begin(), vec.end(), randval);
Looks fine, right? What can we possibly do differently? We can use a lambda:
vector<float> vec(100);
generate(vec.begin(), vec.end(), []() -> float
{
return rand() / (RAND_MAX + 1.0f);
});
Now consider the slightly more complicated example where we have two vectors and want to produce a third vector from them. We can use a variant of std::transform() to do this.
We have vectors invec1 and invec2, and want to produce outvec which is simply the elementwise product of invec1 and invec2.
First try:
float product(float x, float y)
{
return x * y;
}
transform(invec1.begin(), invec1.end(), invec2.begin(), outvec.begin(), product);
Second try:
transform(invec1.begin(), invec1.end(), invec2.begin(), outvec.begin(), [](float x, float y) -> float
{
return x * y;
});
Another application for lambdas is to use one as a sort predicate:
sort(vec.begin(), vec.end(), [](float x, float y) -> bool { return x > y; });
Don't forget, we can always assign a lambda to a variable to clean things up a little:
void somefunc()
{
auto f = [](float x, float y) -> bool { return x > y; };
sort(vec.begin(), vec.end(), f);
}
Now for some code to put it all together:
vector<float> vec(10);
// Fill up the vector with random numbers in [0,1)
generate(vec.begin(), vec.end(), []() -> float { return rand() / (RAND_MAX + 1.0f); });
// Sort the vector in descending order
sort(vec.begin(), vec.end(), [](float x, float y) -> bool { return x > y; });
// Print the vector
copy(vec.begin(), vec.end(), ostream_iterator<float>(cout, " "));
cout << endl;