#5825 closed Bugs (fixed)
constructing function_input_iterator without consuming an item
Reported by: | Owned by: | Dean Michael Berris | |
---|---|---|---|
Milestone: | To Be Determined | Component: | iterator |
Version: | Boost 1.47.0 | Severity: | Showstopper |
Keywords: | function_input_iterator past-the-end | Cc: | mikhailberis@… |
Description
The only constructor for function_input_iterator always consumes an item from the generator. This makes it difficult to define a past-the-end iterator.
The first example given in http://www.boost.org/doc/libs/1_47_0/libs/iterator/doc/function_input_iterator.html calls rand() 11 times instead of the 10 expected. This can be a more serious problem when, for example, reading a file, as shown in the following program:
#include <string> #include <fstream> #include <iostream> #include <algorithm> #include <boost/iterator/function_input_iterator.hpp> static const std::string filename( "test.txt" ); struct generator { typedef int result_type; generator() : in( filename ) {} result_type operator() () { result_type ret; in >> ret; return ret; } std::ifstream in; }; int main(int argc, char * argv[]) { std::ofstream out( filename ); out << 0 << std::endl << 1 << std::endl << 2 << std::endl << 3 << std::endl; generator f; std::copy( boost::make_function_input_iterator(f, 0), boost::make_function_input_iterator(f, 3), std::ostream_iterator<int>(std::cout, " ") ); // "1 2 3" is shown on cout, instead of "0 1 2" return 0; }
A possible solution could be adding a different constructor to function_input_iterator specifically to represent a past-the-end iterator.
Attachments (1)
Change History (9)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
Severity: | Problem → Showstopper |
---|
I agree; this looks like a serious problem.
comment:3 by , 10 years ago
Cc: | added |
---|---|
Owner: | changed from | to
I wasn't watching this and I've just gotten time to take a look at this now. Let me whip up a patch to fix this.
comment:4 by , 10 years ago
Update: I have a patch ready locally, just getting the necessary approvals to release the code under the Boost Software License. If things go well I should have something late Pacific Time, Monday August 27.
comment:6 by , 10 years ago
Status: | new → assigned |
---|
comment:7 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
I have the same problem - here's a simple example where we try to emulate a boost counting iterator. What's particularly nasty is that the two calls to make_function_input_iterator are called in arbitrary order, so the behaviour isn't even defined, as either of the two iterators could end up with the first element.
Here's the output:
I believe the iterators should be modified to never invoke the generator initially until they are dereferenced (so in particular the second iterator should never invoke the generator if used as an end iterator).