@lnxlnxlnx

Что здесь написано?

Столкнулся с задачей, которую не смог осилить собственноручно, обратился к гулугулу. Нашёлся единственный ответ, где мне непонятна перегрузка оператора класса. Последовательность написанного понимаю, но не понимаю суть работы самого алгоритма. Прикладываю код для общего понимания. Работа for_each в целом ясна.
То есть, объект-функция принимает число, записывает значение, получает адрес, сдвигается и так всё повторяется в цикле? Буду очень благодарен за разъяснение молодёжи.
/*
Напишите программу, которая читает последовательность целых чисел из стандартного
ввода с помощью потокового итератора чтения istream_iterator. Нечетные числа
поместите в один файл посредством ostream_iterator, разделяя значения пробелом.
Четные числа таким же образом запишите в другой файл, при этом каждое значение
должно размещаться в отдельной строке.
*/
class OddOrEvenValue
{
    ofstream OddFile, EvenFile;
    ostream_iterator<int> OddOut;
    ostream_iterator<int> EvenOut;

public:

    OddOrEvenValue( 
        const char* odd_file_name, 
        const char* odd_delimiter, 
        const char* even_file_name, 
        const char* even_delimiter)
        : OddFile(odd_file_name, ios_base::out)
        , EvenFile(even_file_name, ios_base::out)
        , OddOut(OddFile, odd_delimiter)
        , EvenOut(EvenFile, even_delimiter)
    {
    }

    void operator( ) ( const int& val )
    {
        (*(val%2 ? OddOut : EvenOut) = val)++;
    }
};
istream_iterator<int> in(cin), eos;
OddOrEvenValue divisor("odd.txt", " ", "even.txt", "\n");
for_each< istream_iterator<int>, OddOrEvenValue& >(in, eos, divisor);
  • Вопрос задан
  • 91 просмотр
Решения вопроса 1
wataru
@wataru
Разработчик на С++, гуглер, экс-олимпиадник.
Почитайте, что делает ostream_iterator.

Если итератору присвоить значение (it = 10;), то оно остается в памяти, при сдвигании итератора вперед (it++;) это значение записывается в выходной файл и следующее присвоение скормит итертору значение в следующей позиции. Этот итератор сделан, чтобы можно было писать в файл, как в C++ коллекцию (например, в вектор).

Важно, что у этого итератора оператор * ничего не делает, возвращает сам итератор. Оператор присвоения, кстати, тоже возвращает сам итератор.

Поэтому конструкция *(val%2 ? OddOut : EvenOut) вернет или итератор OddOut или EvenOut в зависимости от четности val. Далее, конструкция (... = val)++; запишет число val в один из выходных итераторов и сдвинет его на позицию вперед.

Весь код выше создает 2 output_iterator, для двух заданных файлов. Потом for_each через оператор() у класса скармливает ему входные числа из cin (тут работает istream_iterator, который позволяет читать из файлов, как из вектора). А класс, пользуясь конструкцией выше, записывает числа в один из двух файлов в зависимости от четности.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы