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