У меня есть этот фрагмент кода. Объект istream_iterator только определен и не используется, поэтому я ожидаю, что он ничего не сделает, и приложение завершит работу немедленно. Но когда я запускаю приложение, оно не закончится, пока я не предоставлю какой-либо ввод. Зачем?
Я собираю его на ArchLinux с помощью: gcc 4.7.1, с помощью команды: g ++ -std = c ++ 11 filename.cpp
#include <iterator>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
istream_iterator<char> input(cin);
return 0;
}
По стандарту,
24.6.1.1 Конструкторы и деструктор istream_iterator [istream.iterator.cons]
istream_iterator(istream_type& s);
3 — Последствия: Инициализирует в-поток с
&s
, значение может быть инициализирован во время строительства или при первом обращении к нему.
Так что не определено, будет ли эта программа ждать ввода.
Тем не менее, трудно понять, как istream_iterator
может быть реализовано иначе; по 24.6.1: 1, после его создания […] итератор считывает и сохраняет значение T
, так что, если чтение не происходит на строительстве, то это должно произойти на operator *() const
и на свободе operator==(const istream_iterator<T> &, const istream_iterator<T> &)
так что все внутреннее состояние итератора должно быть mutable
,
Предположительно, итератор istream немедленно вызовет cin >> x
извлечь первый токен и определить, должен ли он стать равным конечному итератору. Операция извлечения блокируется до тех пор, пока поток не будет закрыт, токен не будет извлечен или не будет обнаружен сбой анализа.
Обратите внимание, что заголовок вашего вопроса неверен: у вас есть не только объявленный input
, но у вас также есть определенный Это. Если бы ваш код точно отражал вопрос, он сказал бы
extern istream_iterator<char> input; // declaration only!
и не было бы никакой блокировки.
Из потока вы можете «получить» каждое значение только один раз, после чего оно исчезнет. Однако общая потребность в итераторах состоит в том, чтобы обращаться к значению несколько раз без увеличения значения итератора. Таким образом, istream_iterator
извлечет первое значение в конструкции и скопирует его во внутреннее значение, которое затем возвращается при разыменовании итератора.
Это также позволяет итератору определить, находится ли он в конце ввода, и стать конечным итератором. При увеличении читается следующее значение.