Reputation: 215
In the standard I read that you have to create a deafult iterator to be able to know if the iterator has reach end-of stream. I think it's getting quite ugly, isn't there any predefined symbol or equivalent that could help us here?
The default-constructed std::istreambuf_iterator is known as the end-of-stream iterator. When a valid std::istreambuf_iterator reaches the end of the underlying stream, it becomes equal to the end-of-stream iterator.
Here is code example:
std::istreambuf_iterator<char> it(is);
std::istreambuf_iterator<char> end;
if (it != end) { break;}
Why doesn't the iterator has a function named, i.e. hasNext() or isEndOfStream()
Upvotes: 1
Views: 984
Reputation: 385274
isn't there any predefined symbol or equivalent that could help us here?
Yes.
you have to create a deafult iterator to be able to know if the iterator has reach end-of stream
Here it is!
Why doesn't the iterator has a function named, i.e. hasNext() or isEndOfStream()
The singular iterator as sentinel is actually quite elegant. It doesn't introduce any new names into the library, and it allows us to write generic code with start
and end
iterators that doesn't care what kind of thing you're iterating over. That's really important for the standard algorithms.
void bar(const char c);
template <typename Iterator>
void foo(Iterator start, Iterator end)
{
for (Iterator it = start; it != end; ++it)
bar(*it);
}
void version_1()
{
std::istreambuf_iterator<char> start(std::cin);
std::istreambuf_iterator<char> end;
foo(start, end);
}
void version_2()
{
std::vector<char> v{0,1,2,3,4,5};
foo(v.begin(), v.end());
}
Imagine if for containers you had start
and end
, but for streams you had start
and a call to start.hasNext()
? Now, that's not very elegant. That's messy!
Upvotes: 3