В приведенном ниже фрагменте читаются три целых числа из std::cin
; он записывает два в numbers
и отбрасывает третью:
std::vector<int> numbers(2);
copy_n(std::istream_iterator<int>(std::cin), 2, numbers.begin());
Я бы ожидал, что код будет читать ровно два целых числа от std::cin
, но оказывается, что это правильное, стандартно-совместимое поведение. Является ли это надзором в стандарте? В чем причина такого поведения?
От 24.5.1/1 в стандарте С++ 03:
После того, как он будет построен, и каждый используется время ++, итератор читает и сохраняет значение
T
.
Итак, в приведенном выше коде в точке вызова итератор потока уже считывает одно целое число. С этого момента каждый, прочитанный итератором в алгоритме, является прочитанным вперед, что дает значение, кэшированное из предыдущего чтения.
Последний черновик следующего стандарта n3225, похоже, не имеет никаких изменений здесь (24.6.1/1).
В соответствующей заметке 24.5.1.1/2 текущего стандарта в отношении конструктора istream_iterator(istream_type& s)
читает
Эффекты: Инициализирует
in_stream
с помощьюs
.value
может быть инициализирован во время строительства или в первый раз ссылка.
С акцентом на "value
может быть инициализировано...", в отличие от " должен быть инициализирован". Это звучит противоречащим 24.5.1/1, но, возможно, это заслуживает отдельного вопроса.