вторник, 5 января 2016 г.

Невидимые байты istream_iterator'а

Идея использовать разные однопроходные алгоритмы над потоком данных без копирования этих самых данных давно крутиться в моей голове и использование istream_iterator<char> над ifstream вместо вычитывания содержимого файла в память с последующим обходом этого самого содержимого кажется чрезмерно клёвой идеей, но...

istream_iterator<T> использует operator>>(std::istream&, T&) для вычитывания данных, который для char определён так, что пробельные символы выбразываются. Они же нивидимые, вот и итератор их тоже с чего-то не видит. Тут налицо некое проявление маразма, но, когда речь заходит о потоках из стандартной библиотеки C++, слова "маразм" и "бред" на долго прописываются в головах ведущих эту речь и едиственный вопрос который реально важен это как с оными словами бороться в данном конкретном случае. Ответ кроестя во флаге std::ios_base::skipws, который по умолчанию взведён. Его сброс позволяет написать утилиту cat вот таким образом:

std::ifstream is(some_path);
is.unsetf(std::ios_base::skipws);
std::copy(
  std::istream_iterator<char>(is), std::istream_iterator<char>(),
  std::ostream_iterator<char>(std::cout)
);