Standard algorithms are cool

Using standard algorithms our code gets easier to read, write, and modify. And even better if we throw in lambda functions. Here we are seeing an example showing how std::transform() looks better than a for loop.

We have to write a piece of code that gets in input an array of doubles and puts them, increased by 42 and keeping their order, at the beginning of a deque.

Let's say this is the array of doubles:

const int DIM = 10;
double data[DIM] = { 0.23, 1.54, 2.44, 3.45, 4.98, 5.93, 6.34, 7.28, 8.58, 9.41 };
dump(data, data+DIM);

And this is the deque:

std::deque<double> d;
d.push_back(999); // this should stay at the end

We can't use push_back(), because the element(s) already in the deque should be kept at the end of it. We can't use push_front() because we would get the unrequired special effect of reversing the data order. We should use insert().

Here is a "classical" solution to our problem, by for loop:

std::deque<double>::iterator pos = d.begin();
for(int i = 0; i < DIM; ++i)
pos = d.insert(pos, data[i] + 42) + 1;

We need to refresh our current position (pos iterator) after the call to insert(), since it invalidates its old value, and we increase it to avoid falling back in the push_front() behaviour.

Once one is accustomed to the standard transform() algorithm, this version of the same code looks clearer:

std::transform(data, data + DIM, inserter(d, d.begin()),
std::bind2nd(std::plus<double>(), 42));

Actually, there are a few features that could look surprising, at first. Maybe you need to get acquainted to inserters, to the binders, or to the standard functor. But after a while all of this would look natural to you.

Moreover, we could avoid using a binder and the plus functor here, if we use a lambda function instead - that makes the code even more clear:

std::transform(data, data + DIM, inserter(d, d.begin()),
[] (double v) { return v + 42; } );

Item 43 of Effective STL, one of the Effective C++ book series by Scott Meyers, is about standard algorithm as a way of writing better C++ code.

No comments:

Post a Comment