SvenG
SvenG

Reputation: 65

Why do I need another iterator as an argument in std::copy()?

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

Answers (3)

xdavidliu
xdavidliu

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

lubgr
lubgr

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

463035818_is_not_an_ai
463035818_is_not_an_ai

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

Related Questions