The section 12.9 (page 380) in the TDPL books presents foreach overloading.
However the example shown is problematic because there is no
method of automatic initializing of the _root variable without which foreach
overloading cannot work properly (obviously the loop steering
variable has to be initialized each time the loop is created). I tried to
consult the language reference but the section devoted to
operator overloading does not have any information about foreach overloading.
Where can I find definitive information about this feature?
What is the reason for discrepancy between TDPL book and the web language
reference?

The section 12.9 (page 380) in the TDPL books presents foreach overloading.
However the example shown is problematic because there is no method of
automatic initializing of the _root variable without which foreach
overloading cannot work properly (obviously the loop steering variable has
to be initialized each time the loop is created). I tried to consult the
language reference but the section devoted to operator overloading does
not have any information about foreach overloading. Where can I find
definitive information about this feature? What is the reason for
discrepancy between TDPL book and the web language reference?

I think that you're taking the term "foreach overloading" a bit too literally.
The two ways to get your type to work with foreach are to make it an input
range (so, it defines the primitives front, popFront, and empty), or to have
it define opApply. TDPL explains this. There is no overloaded operator for
foreach.
The example on p.380 is only attempting to show you the necessary primitives
to make the type work with foreach, not define the entire type (hence why it
doesn't do anything about initializing _root). Notice the ... after the
definition for popFront.
When foreach is used on a type which defines the primitives for an input
range, the loop gets translated from
foreach(i; range)
{
//...
}
to
for(; !range.empty; range.popFront())
{
auto i = range.front;
//...
}
The range is then consumed by the foreach loop. The containers in
std.container overload opSlice to return a range over their elements, and that
would be a typical way to get a range over a container.
- Jonathan M Davis