1

I am using the code from this answer to read lines of numbers (one number per line) from a file into a vector:

ifstream fs(file_name);
vector<double> v {istream_iterator<double>{fs}, istream_iterator<double>{}};
fs.close();

which works neatly and fine. My questions are:

  1. How does it work? @user470379 posted an "equivalent" piece of code by expanding it into a while loop. I understand the loop but I don't see the equivalence.
  2. Why were people criticizing? Besides the delimiter or quote issues that I don't care about here, some people like @StudentT and @XanderTulip said it is highly inefficient. Since I don't know how it works, I cannot get the inefficient part. But I also don't think the delimiter issue can cause performance problem as stated by @StudentT ("...therefore not scalable...").

Thank you.

Community
  • 1
  • 1
Ziyuan
  • 4,215
  • 6
  • 48
  • 77

3 Answers3

2

How does it work?

It initialises the vector by copying from a range of iterators which read from the stream. The initial iterator, given the stream, reads a double from the stream each time it's incremented. When it reaches the end, it compares equal to the default-constructed iterator used to mark the end of the range.

Why were people criticizing?

The code in that answer is for splitting a string, and as such is rather inefficient - there are ways of viewing substrings without first copying it, then allocating lots of small strings. Your code is rather different - reading an array of numbers from a file - and is a reasonably efficient way of doing that.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

For the first question:

istream_iterator<double>{fs} is an iterator to the begining of the file stream.

istream_iterator<double>{} is an iterator to the end of the stream.

vector is initialized using the above [first, last) range.

911
  • 908
  • 8
  • 16
0

1.How does it work? @user470379 posted an "equivalent" piece of code by expanding it into a while loop. I understand the loop but I don't see the equivalence.

The std::istream_iterator maps the iterator concept on an input stream: It maps the operation of incrementing the iterator to a read operation (to a variable of the bound type) and the dereference iterator operation to providing this value to client code.

This effectively allows you to treat any input stream as an iterable sequence (and hook in any code from STL that works with generic iterators).

2.Why were people criticizing? Besides the delimiter or quote issues that I don't care here, some people like @StudentT and @XanderTulip said it is highly inefficient.

It is not inefficient (not in a time/memory complexity sense anyway) but it may be a bit slow (I don't know if that is the case - measure and find out).

As always, write the code in an idiomatic way. If it is inefficient, then measure and optimize afterwards, as necessary.

utnapistim
  • 26,809
  • 3
  • 46
  • 82