Boost logo

Boost :

Subject: Re: [boost] [iterator] iterator_facade reference type problem
From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2010-01-15 06:37:52

Jeffrey Hellrung wrote:
> Phil Endecott wrote:
>> I've done some more experiments, and it seems to work with
>> std::pair<const KEY, value&> if i write (*iter).second rather than
>> iter->second.
>> Looking at the iterator_facade source, operator-> calls operator* and
>> passes the result to operator_arrow_result::make(). This takes its
>> address and, because std::pair<const KEY,VALUE&> is not a reference, it
>> tries to convert it to operator_arrow_proxy<...>. This fails because
>> std::pair<const KEY,VALUE&> is not convertible to std::pair<KEY,VALUE>.
>> I think I just want operator-> to return a pointer to my reference type,
>> but the operator_arrow_result stuff is trying to do something more
>> complicated. In what case is the operator_arrow_proxy useful? Is there
>> some way to get what I want using iterator_facade?
> <snip>
>> BTW I have been testing with an oldish version of Boost, but I've looked
>> at the source in svn and it doesn't seem to have changed much.
>> Cheers, Phil.
> (Also looking at the code) operator_array_proxy should be probably be
> instantiated with the Reference, not ValueType...??? Would that be
> correct? I.e., operator_array_proxy should wrap a reference (which is
> not a real C++ reference), not a value...
> You *could* just overload operator-> in the derived class to do
> something else (in this case, I would say try using a proxy that wraps a
> reference).
> Also, just to be clear, the operator_array_proxy stuff in
> iterator_facade fails not because std::pair< const KEY, VALUE& > isn't
> convertible to std::pair< KEY, VALUE >, but because their pointers
> aren't convertible. At least that's what I'm seeing...
> Seems like I stumbled on this in the past and rather than figure out
> what was wrong, I just redefined operator-> in the derived class to work...

Hi Jeff,


There seem to be a couple of issues here. Firstly, as you say
operator_arrow_proxy is being instantiated with the ValueType but there
would be more chance of it working if it were instantiated with the Reference.

Secondly, std::pair containing a non-const reference for the value
causes a "forming reference to reference" error in
(is_convertible_basic_impl gcc version; is_convertible.hpp line 137).
Is this a SFINAE issue? This is being called from
iterator_facade_default_category "check for readability". I'm out of
my depth trying to track this down any further.

I have fixed it, presumably as you did, with a custom pair-like type
and a custom arrow_proxy type, something like this:

struct iter_ref_t { // replacement for std::pair
   const KEY first;
   VALUE& second;
   iter_ref_t(const KEY first_, VALUE& second_): first(first_),
second(second_) {}

class iterator:
   public boost::iterator_facade<iterator,
   iter_ref_t dereference() const { return iter_ref_t(....); }

   struct arrow_proxy { // replacement for iterator_facade::operator_arrow_proxy
     mutable iter_ref_t r;
     arrow_proxy(const iter_ref_t& r_): r(r_) {}
     iter_ref_t* operator->() const { return &r; }

   arrow_proxy operator->() const { // override version in iterator_facade
     return arrow_proxy(dereference());


Would any Boost.Iterator experts care to comment?

BTW it seems to me that the operator_arrow_proxy thing is really a sort
of "smart pointer" - it's an object that looks like a pointer, but it
always points to an object that it contains. Does it have more general applications?

Regards, Phil.

Boost list run by bdawes at, gregod at, cpdaniel at, john at