Верьте или нет, эта строка не объявляет экземпляр std::vector
с именем results
, вызывая конструктор, принимающий итератор начала и конца:
std::vector<float> results(std::istream_iterator<int>(actualLineStream),
std::istream_iterator<int>());
На самом деле объявляет функцию с именем results
, которая принимает параметр с именем actualLineStream
и другой безымянный параметр, оба типа std::istream_iterator<int>
.
Обычно в C ++, если что-то выглядит как функция, оно будет проанализировано как единое целое; стандарт C ++ требует этого. Это действительно для обратной совместимости с C - но это настолько нелогично, что у него даже есть собственное имя: "самый неприятный синтаксический анализ" . Некоторые компиляторы даже выдают предупреждение, если встречаются самые неприятные разборы.
Это связано с тем, что эти две строки не эквивалентны в C ++:
Foo bar; // Declares an instance of Foo named bar
Foo bar(); // Declares a function named bar that takes no parameters and returns a Foo
Чтобы исправить это, вы можете добавить несколько скобок вокруг одного из аргументов:
// +--------- Note extra parentheses!! ---------+
// | |
// V V
std::vector<float> results((std::istream_iterator<int>(actualLineStream)),
std::istream_iterator<int>());
Или просто объявить каждый итератор отдельно:
std::istream_iterator<int> resultsBegin(actualLineStream);
std::istream_iterator<int> resultsEnd;
std::vector<float> results(resultsBegin, resultsEnd);