Boost logo

Boost Users :

Subject: Re: [Boost-users] iterator_adaptor: making dereference of adapted tree node* return node value
From: Rob Desbois (rob.desbois_at_[hidden])
Date: 2012-02-24 05:51:43

On 23 February 2012 14:39, Robert Jones <robertgbjones_at_[hidden]> wrote:
> I favoured the type traits magic approach, and publish the resulting value
> type as the
> value type of the iterator...
> typedef typename if_<is_const<NODE>, const typename NODE::value_type, typename NODE::value_type>::type value_type;

Thanks for the input Rob - see below for the solution I settled on.

On 23 February 2012 18:58, Jeffrey Lee Hellrung, Jr.
<jeffrey.hellrung_at_[hidden]> wrote:
> To reiterate Robert Jones' reply, yes, AFAIK, a const iterator should pass a
> const-qualified value_type to iterator_facade/iterator_adaptor, as implied
> by the constant node_iterator example in the docs:

Actually iterator_facade/iterator_adaptor's value type in the
tutorials is the _node_ type, not the node's value_type.

> On a related note, you should specify your reference type you pass to
> iterator_adaptor explicitly as the return type of your dereference member
> function. Otherwise I think you'll end up returning a reference to a
> temporary within operator*. I believe that's *actually* what the quoted
> error is trying to tell you.

Thanks - I've updated to use
node_iterator::iterator_adaptor_::reference as the return type from
dereference(). The docs show that this defaults to Value&.
The error message still stands though, since const
node_type::value_type is still not const.

I settled on implementing the boost::mpl::if_ method as shown by Rob,
which turned out to be a viable solution to the problem I faced, but
then after some more thinking and coding realised that I didn't
actually want the mutable iterator type to enable modification of the
data in the referenced node. Since this is an ordered tree, modifying
the data of a node is clearly a Bad Thing!
Feeling somewhat silly that I didn't recognise this before leaping
down the rabbit hole...what I now have is that Value is *always*
   template< class NODE >
   node_iterator: public boost::iterator_adaptor<
      node_iterator<NODE>, // Derived
      NODE*, // Base
      const typename NODE::value_type // Value

The reference type is then const typename NODE::value_type& as
expected and everything works fine. It was only after discovering that
std::set and friends' iterators can be the same type as the
const_iterator that this finally clicked!

Thanks for the guidance, nice to know I wasn't going completely off my
rocker with the mpl approach :-D

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at