Is there such a thing as a std::istream const iterator?
The following code won't compile because the std::istream_iterator in foo() can't bind to the const std::istream reference to the temporary object created in main().
// main.cpp
#include <iostream>
#include <sstream>
#include <iterator>
void foo( const std::istream& s )
{
std::istream_iterator<char> i( s );
// No std::istream_const_iterator, but anything by another name?
std::cout << *i;
}
int main( int argc, char* argv[] )
{
std::string p( "abcdefghijklmnopqrstuvwxyz" );
foo( std::stringstream(p) );
return 0;
}
Is there a istream iterator that can bind to a const istream?
Having just asked this question, I just learned that istream_iterator ctors initialize and perform the first read. I guess I'm still not clear: does that read necessarily modify the bound istream? If not, it seems like there ought to be some kind of const iterator that can bind to a const istream, no?
$ g++ --version
g++ (GCC) 9.2.1 20190827 (Red Hat 9.2.1-1)
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -g ./main.cpp && ./a.out
./main.cpp: In function ‘void foo(const istream&)’:
./main.cpp:84:34: error: binding reference of type ‘std::istream_iterator<char>::istream_type&’ {aka ‘std::basic_istream<char>&’} to ‘const istream’ {aka ‘const std::basic_istream<char>’} discards qualifiers
84 | std::istream_iterator<char> i( s );
| ^
In file included from /usr/include/c++/9/iterator:66,
from ./main.cpp:80:
/usr/include/c++/9/bits/stream_iterator.h:68:38: note: initializing argument 1 of ‘std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator(std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type&) [with _Tp = char; _CharT = char; _Traits = std::char_traits<char>; _Dist = long int; std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type = std::ba
sic_istream<char>]’
68 | istream_iterator(istream_type& __s)
| ~~~~~~~~~~~~~~^~~
Yes.
istream_iteratoris a convenience class that allows one to treatistreamobjects as though they are containers such as astd::vectoror an array.Underneath, the
istreamis the object used to read from the stream. And yes, reading from a stream does modify anistream. How else would theistreamkeep track of internal state to indicate whether the attempt to read was successful or not, how many characters were read, etc.?Since you need a non-
const istreamobjects to read, it make no sense to be able to construct aistream_iteratorfromconst istreamobjects.