C++ for_each Hurts My Head

I admit that this is my personal pet peeve. I hate C++ for_each.

The foreach statement is a syntactic sugar that traverse a collection of items.

It offers better clarity than C style for loops because it does not require an index counter, or an iterator.

foreach item in collection
	do stuff to item

This features is available in most modern programming languages, and they are very well-done.

C++ doesn’t support foreach natively. Instead, it is done in a template function, and it hurts my brain.

foreach – the C++ Way

Let’s take a look at the VC90 implementation of for_each in STL.

// TEMPLATE FUNCTION for_each
template<class _InIt,
	class _Fn1> inline
	_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
	{	// perform function for each element
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Func);
	_CHECKED_BASE_TYPE(_InIt) _ChkFirst(_CHECKED_BASE(_First));
	_CHECKED_BASE_TYPE(_InIt) _ChkLast(_CHECKED_BASE(_Last));
	for (; _ChkFirst != _ChkLast; ++_ChkFirst)
		_Func(*_ChkFirst);
	return (_Func);
	}

[Update: The for_each code is modified to match completely with VC90. I didn’t do a good job before, and it was pointed out by my colleague]

C++ for_each is a template function that takes in two iterators that defines the first and last of a sequence, and a function pointer or an operator() that performs on an item of the sequence.

In Scott Meyer’s Effective STL, he has argued that for_each makes code more direct and straightforward.

So here is an example from directly from the book.

// function object that performs action on an integer
// adaptable as a function object
class DoSomething : public unary_function<int,void>
{
	void operator()(int x) {...}
	...
};
int main()
{
	deque<int> di; // a deque of integer
	...
	DoSomething d; // function object

	// oh god, what's this
	for_each<DequeIntIter, DoSomething&>(
		di.begin(),
		di.end(),
		d);
}

No matter how many times I look at this, it is not intuitive to me. The template syntax is obscure, and I don’t get a sense that there is a loop in the code.

I tried to get used to it, I really did. But after all these years, I have finally given up.

Strangely, some of my colleagues feel the same way.

Maybe it is not just me …

Going back to one of my CS courses in my M.S, I remember reading a study on how programmers review code.

The idea is to analyze a programmer’s eye movement during code review. This eye movement is called the scan pattern.

The results were very interesting. In general, programmers tend to spend a third of the time scanning most of the function. And then, they will spend the remaining time going back and forth within a loop.

In hindsight, this is not surprising. Loops often holds the most complex logic in a function. To understand the logic, programmers need to spend time “unrolling” the loop mentally to see the side effects of each iteration.

If the study is accurate, then it certainly explains why C++ for_each is difficult to read.

Conclusion

I will avoid C++ for_each at all cost.