
"Keith MacDonald" <boost@mailclan.net> writes:
Hi,
I'm stuck trying to use iterator_adaptor from the CVS head. I simply want to derive a non-const iterator from a const one derived from iterator_facade, as shown in the code below.
Answer: don't do that. Making iterators by derivation from other iterators is almost always an error (and in your case also: for example the return type of operator++ is wrong on the derived iterator). Make a new constant iterator type with iterator_facade. If you do it right, it will interoperate properly with your mutable iterator.
When I compile it with VC7.1, the line marked "/* *ERROR* */" generates one of those impenetratable error messages that starts with:
cannot convert from 'const Node' to 'boost::iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Differen ce>::reference'
Compile with GCC; you'll get better error messages. The type 'boost::iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference>::reference' is almost certainly 'Node&', which can't be bound to a 'const Node'.
If I delete that line, so the default is used, dereferencing a non-const iterator returns a const Node. This seems such a simple requirement that there must be an easy way to do it. What am I doing wrong?
Looks like a job for iterator_adaptor: // untested template <class V> struct iter : boost::iterator_adaptor<iter<V>, V*, V, boost::bidirectional_traversal_tag> { typedef boost::iterator_adaptor<iter<V>, V*, V, boost::bidirectional_traversal_tag> super; iter() {} template <class V2> iter(iter<V2> x, boost::enable_if_convertible<V2*,V*>::type* = 0) : super(x.base()) friend class iterator; friend class boost::iterator_core_access; private: void increment() { base() = base()->next(); } void decrement() { base() = base()->prev(); } }; typedef iter<Node> iterator; typedef iter<Node const> const_iterator; HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com