views:

87

answers:

2

g++ allows this construction of an istream_iterator from an ifstream instance:

std::ifstream ifstr("test.txt");
std::istream_iterator<std::string> iter1(ifstr);

...but it doesn't allow the same construction with an unnamed temporary:

std::istream_iterator<std::string> iter2(std::ifstream("test.txt"));

This gives:

error: no matching function for call to ‘std::istream_iterator, ptrdiff_t>::istream_iterator(std::ifstream)’

Does anyone know why this doesn't work? - thanks!

+6  A: 

It doesn't, because istream_iterator's constructor parameter is a non-const reference, but you provide a temporary. You cannot provide temporaries (that are rvalues) to non-const references.

But aside, even if it would take a const reference, it would still not work, because ifstream is not copyable. Curiously, C++ requires an accessible copy constructor to bind an rvalue to a non-const reference.

Johannes Schaub - litb
Thanks, Johannes!
Stumped6789
And then again, if that was allowed you would be creating an iterator to an already destroyed ifstream, and that would UB
David Rodríguez - dribeas
+1  A: 

The stream is passed by non-const reference, but a temporary can only be passed by const-reference.

Streams are essentially always passed by non-const reference, because almost anything you do with a stream can/will modify the stream's state.

Jerry Coffin