That is a very good question. I have honestly no idea why they did it. The problem is that input_order stores iterators to strings. Hence the bolded copy line sends iterators to an output iterator that is expecting a string.

I was able to get it compiling by...
Code:
typedef list<WordIter> Index;
to
typedef list<string> Index;

input_order.push_back(ref.first);
to
input_order.push_back(*ref.first);
Another solution might be (more efficient):
Code:
Replace
copy(input_order.begin(), input_order.end(), ostream_iterator<string>(cout, "\n"));
by
for_each(input_order.begin(), input_order.end(), [](WordIter it) { std::cout << *it << "\n"; });
(Requires C++0x.)