Почитайте, что делает
ostream_iterator.
Если итератору присвоить значение (
it = 10;
), то оно остается в памяти, при сдвигании итератора вперед (
it++;
) это значение записывается в выходной файл и следующее присвоение скормит итертору значение в следующей позиции. Этот итератор сделан, чтобы можно было писать в файл, как в C++ коллекцию (например, в вектор).
Важно, что у этого итератора
оператор * ничего не делает, возвращает сам итератор.
Оператор присвоения, кстати, тоже возвращает сам итератор.
Поэтому конструкция
*(val%2 ? OddOut : EvenOut)
вернет или итератор OddOut или EvenOut в зависимости от четности val. Далее, конструкция
(... = val)++;
запишет число val в один из выходных итераторов и сдвинет его на позицию вперед.
Весь код выше создает 2 output_iterator, для двух заданных файлов. Потом for_each через оператор() у класса скармливает ему входные числа из cin (тут работает
istream_iterator, который позволяет читать из файлов, как из вектора). А класс, пользуясь конструкцией выше, записывает числа в один из двух файлов в зависимости от четности.