Reputation: 65
I don't understand why I need to put another iterator as the second argument in the call to std::copy()
for reading through a file. How is iterator 'end' ending of a file?
vector<Point> v;
istream_iterator<Point> is(file), end;
copy(is, end, back_inserter(v));
Upvotes: 5
Views: 156
Reputation: 3042
I believe the question is asking why std::copy
doesn't just stop copying when it encounters an actual EOF
(end-of-file) character in the file rather than the contrived method of passing in a default-constructed iterator.
std::copy
is a generic algorithm that works on many containers that have iterators. Copying from vectors or arrays requires both start and end input iterators, since in vectors and arrays there are no corresponding EOF markers. Since we want to use the same copy
program for files, file iterators are intended just for this purpose, and the implementation likely does something like
if the file iterator points to
EOF
, then set it to the default constructed value
which is of course trivial to implement. Of course, it is possible to have a function called like file_copy(file, destination)
, but then it would be a different interface from the standard std::copy
that we are used to, and we would be using a different copy
function for files as we do for arrays and vectors.
Upvotes: 0
Reputation: 38267
How is iterator 'end' ending of a file?
By convention and/or a design decision in the standard library. The iterator end
is default-constructed, and on cppreference, we learn about the default std:istream_iterator
constructor:
constexpr istream_iterator();
Constructs the end-of-stream iterator, value-initializes the stored value [...]
The deeper reasoning is that the standard algorithms are built around the concept of a half-open range, often denoted as [first, last)
. The is
iterator must be distinguished from some kind of end sentinel last
- otherwise, std::copy
can't know when reading from the input is not meaningful anymore (i.e., when it has reached the end of the file). In your case, this is end
.
Upvotes: 2
Reputation: 122133
Why?
You need to tell the algorithm somehow how many elements it should copy. Note that copy
is generic and the reason to use iterators is to be agnostic of the actual container. Hence, the algorithm has no way to stop when it reaches the end of the container. All it has is the two iterators you pass it.
How?
This is just how it is defined in the language. If you look at the constructor that takes no arguments you see that it creates a special end-of-stream iterator. From cppreference:
constexpr istream_iterator(); (1)
1) Constructs the end-of-stream iterator, value-initializes the stored value. This constructor is constexpr if the initializer in the definition auto x = T(); is a constant initializer.
Upvotes: 2