By using foreach, you are letting the compiler decide on the optimization rather than worrying about it yourself. For example - are pointers or indices better? Should I cache the termination condition or not? Should I rotate the loop or not? The answers to these questions are not easy, and can vary from machine to machine. Like register assignment, let the compiler do the optimization.
for (int i = 0; i < foo.length; i++)
or:
for (int i = 0; i < foo.length; ++i)
or:
for (T* p = &foo[0]; p < &foo[length]; p++)
or:
T* pend = &foo[length];
for (T* p = &foo[0]; p < pend; ++p)
or:
T* pend = &foo[length];
T* p = &foo[0];
if (p < pend)
{
do
{
...
} while (++p < pend);
}
and, of course, should I use size_t or int?
for (size_t i = 0; i < foo.length; i++)
Let the compiler pick!
foreach (v; foo)
...
Note that we don't even need to know what the type T needs to be, thus avoiding bugs when T changes. I don't even have to know if foo is an array, or an associative array, or a struct, or a collection class. This will also avoid the common fencepost bug:
for (int i = 0; i <= foo.length; i++)
And it also avoids the need to manually create a temporary if foo is a function call.
The only reason to use a for loop is if your loop does not fit in the conventional form, like if you want to change the termination condition on the fly.