Инициализация значения входного итератора

Я читаю главу 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 является экземпляром шаблона. Запись istream_iterator() запускает инициализацию значения для объекта istream_iterator, что означает нулевую инициализацию + вызов неявного конструктора по умолчанию ( http://en.cppreference.com/w/cpp/language/value_initialization). Я думал, что инициализация по умолчанию объекта istream_iterator также будет работать (вызывает вызов конструктора по умолчанию), поэтому я попробовал это:

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));

Но это не компилируется:

ошибка: ожидаемое первичное выражение перед токеном ','

Я не понимаю, что происходит. Любое объяснение приветствуется.

4 ответа

Решение

Там нет никакого способа инициализации по умолчанию, а не инициализации значения, временный. Хотя выражение type() создает инициализированное значением временное, одно только имя типа не является допустимым выражением.

Однако для любого типа (такого как этот), который объявляет конструктор по умолчанию, инициализация по умолчанию и инициализация значения эквивалентны; нет инициализации нуля до вызова неявного конструктора.

Не отвлекайтесь на шаблон. Та же проблема возникнет с любым именем типа:

struct S {};

void f(int, S);

f(1, S);   // error: S is not an object
f(1, S()); // okay: S() constructs an object

В данном контексте:

copy(istream_iterator<int>(cin), istream_iterator<int>, back_inserter(v));
//                               ^^^^^^^^^^^^^^^^^^^^^

второй аргумент, istream_iterator<int> анализируется как тип. Вам нужен экземпляр, поэтому вам нужен ()с аргументами или без Кроме того, следующее не будет работать:

void foo(int); // function declaration

int main()
{
  foo(int);
}

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));

Другие вопросы по тегам