
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, s/operator_array_proxy/operator_arrow_proxy/g 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<pair<KEY,VALUE&>,pair<KEY,VALUE>> (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, std::pair<KEY,VALUE>, boost::bidirectional_traversal_tag, iter_ref_t> { 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; } }; public: 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.