1.1 Lambda Functions
1. (First Encounters with Lambda Functions)
The objective of this exercise is to get you acquainted with lambda function syntax by examining some simple examples. Lambda functions are very important and useful and we shall be using them in other examples during the course.
In this exercise we concentrate on defining lambda functions that process arrays of double precision numbers (or integers) in various ways. In general, you need to think about a lambda’s signature, that is its return type and input arguments.
Answer the following questions:
a) Create a lambda function that multiplies each element of an array by a number. This number is a captured variable; test the function for the cases when it is copy-by-value and a reference. The original array is modified after having called the function.
b) Print the values of the modified array using autoto initialise the iterator variable instead of declaring it explicitly.
c) Write a lambda function to compute both the minimum and maximum of the elements in an array. The return type is an std::pair(or if you prefer, std::tuplewith two elements) containing the computed minimum and maximum values in the array.
d) Compare the approach taken in part c) by calling std::minmax_element. For example, do you get the same output? How easy is to understand and reuse the code?
2. (Comparing Lambda Functions with Function Objects and Free Functions)
The objective of this exercise is to examine the application of lambda functions in C++ code. In this case we test some STL algorithms. In particular, we examine std::accumulate(by the way, it has two forms) that is a special fold function that iterates over the elements of an array and accumulates them in some way to produce scalar output. Consider the code to accumulate the elements of an array in some way. In other words it is a scalar-valued function that maps a vector to a scalar value.
The start code uses three functions, two of which are user-defined and the other is a predefined STL function object. The first two functions are:
// N.B. Generic lambda
auto MyMultiply = [] (auto x, auto y) { return x*y ;};
struct FOMultiply {
template <typename T>
T operator () (const T& x, const T& y) { return x * y; }
};
and the algorithm is:
std::vector<int> vec { 1,2,3,4,5 };
int acc2 = std::accumulate(vec.begin(), vec.end(), initVal, std::multiplies<int>());
int accA = accumulate(vec.begin(), vec.end(), initVal, FOMultiply());