http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51823
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-01-11 13:55:49 UTC --- (In reply to comment #0) > Headerfiles involved: > <iterator> And <iostream> > Consider an iterator class that implements the requirements of a > forward_iterator. Do you mean bidirectional iterator? You can't reverse a forward iterator, and std::reverse_iterator requires that its template parameter meets the requirements of a Bidirectional Iterator. Your class doesn't implement those requirements, it doesn't have a post-increment operator. And as I said in my previous comment, the iterator requirements say operator* returns the iterator's 'reference' type. reverse_iterator::operator* then returns the same thing because the 'reference' type is, in effect, defined as "the type returned by operator*" (Also, the name __traits is forbidden, names beginning with double-underscore are reserved for the implementation) > The 'work-around' forces the use of forwarding. I put it as comment in the > minimum example. If I should have attached a separate source file with just > the > operator*()-line replaced, I wish to express my apologies in advance. The preprocessor strips comments out, so the workaround isn't in the attached file. The first problem is that your class lies, saying its 'reference' type is a reference, but then returning something different from operator*. That causes a reference to be bound to a temporary, as you'll see if you compile with -Wsystem-headers to enable warnings for code in the standard library headers. The second problem is how reverse_iterator::operator* is defined: reference operator*() const { _Iterator __tmp = current; return *--__tmp; } This creates a temporary iterator, then returns a reference to its d_val member. By the time that's written to std::cout the temporary has been destroyed. For a bidirectional iterator the expression *r-- is required to be valid, so your type fails that requirement. What you've written is not an iterator, it's a generator. It doesn't meet the iterator requirements, so can't be used with std::reverse_iterator and std::copy and other templates that require iterators.