Я читаю главу 8 книги «Ускоренный C ++». Раздел 8.3 посвящен входным и выходным итераторам:
[…]vector<int> v; // read ints from the standard input and append them to v copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(v));
Второй аргумент для копирования создает значение по умолчанию (пусто)
istream_iterator, который не связан ни с одним файлом.
Тип istream_iterator имеет значение по умолчанию со свойством, которое любое
istream_iterator, который достиг конца файла или находится в состоянии ошибки
будет казаться равным значению по умолчанию. Поэтому мы можем использовать
значение по умолчанию для обозначения соглашения «один за другим» для
копия.
Вот что я понимаю: istream_iterator является классом шаблона, а istream_iterator< int> является экземпляром шаблона. Написание istream_iterator< int> () запускает инициализацию значения istream_iterator< int> object, что означает нулевую инициализацию + вызов неявного конструктора по умолчанию (http://en.cppreference.com/w/cpp/language/value_initialization). Я думал, что по умолчанию инициализация istream_iterator< int> object тоже будет работать (вызывает вызов конструктора по умолчанию), поэтому я попробовал это:
vector<int> v; // read ints from the standard input and append them to v copy(istream_iterator<int>(cin), istream_iterator<int>, back_inserter(v));
Но это не компилируется:
ошибка: ожидаемое первичное выражение до токена ‘,’
Я не понимаю, что происходит. Любое объяснение приветствуется.
Там нет никакого способа инициализации по умолчанию, а не инициализации значения, временный. Хотя выражение type()
создает инициализированное значением временное, одно только имя типа не является допустимым выражением.
Однако для любого типа (такого как этот), который объявляет конструктор по умолчанию, инициализация по умолчанию и инициализация значения эквивалентны; нет инициализации нуля до вызова неявного конструктора.
В данном контексте:
copy(istream_iterator<int>(cin), istream_iterator<int>, back_inserter(v));
// ^^^^^^^^^^^^^^^^^^^^^
второй аргумент, istream_iterator<int>
анализируется как тип. Вам нужен экземпляр, поэтому вам нужен ()
с аргументами или без Кроме того, следующее не будет работать:
void foo(int); // function declaration
int main()
{
foo(int);
}
Не отвлекайтесь на шаблон. Та же проблема возникнет с любым именем типа:
struct S {};
void f(int, S);
f(1, S); // error: S is not an object
f(1, S()); // okay: S() constructs an object
istream_iterator
это «шаблонный» класс
Предоставляет два конструктора:
basic_istream<charT,traits>* in_stream;
istream_iterator() : in_stream(0) {}
istream_iterator(istream_type& s) : in_stream(&s) { ++*this; }
Конструктор по умолчанию инициализирует in_stream
в 0
используется для конца потока
Так,
istream_iterator<int>
необходимость ()
для EOF
Исправлено: —
copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(v));