Tobias Schwinger wrote:
David Abrahams wrote:
But why not just change the interface in your dereference function and hand back a real reference at that point? If you are not storing a copy of the value_type within the proxy, I don't see what the proxy can be buying you.
I'll put a short problem-domain-specific excursion at the end of this post which explains what exactly the proxy is buying me.
Thanks.
So now we come to this one. This one is entirely in the hands of the library to prevent, since the user doesn't usually determine the return type of operator->. It seems like a bad idea to allow it silently. The library is supplying an operator-> that stores an object of the value_type. There are very few situations where modifications to that object can go anywhere useful, so it makes sense to prevent them.
Doesn't the fact that reference and value_type are the same and both are mutable class types indicate that this should work as well ?
Ah. Well now, that is a special case. Maybe we should allow it whenever reference is the same as or derived from value_type. Incidentally, I don't call that case a proxy -- as far as I'm concerned that's just an ordinary non-lvalue iterator. I suppose if your value_type is really a refcounted pimpl it is somewhat proxy-like, though. Incidentally #2, the library is focused mainly on building generic iterators so we usually didn't consider the fact that class value_type objects returned by value from an iterator's operator* might be assigned into.
After all, it should be just another notation for
(*i).mutator(value)
from a user's perspective.
The library is able to make sensible default choices without fear because the user can always reimplement any operator within his derived iterator.
My workaround to allow it feels somewhat ugly, because I have to redundantly do the same thing iterator_facade does already (use yet another proxy to aggregate my temporary reference object and make its operator-> return a pointer to it - just like operator_arrow_proxy (given that reference and value_type are the same), except that there is a non-const operator->, too).
Understandable.
!!! However, it works for me. I don't want to try to make you change things for what could be a special case !!!
I'm not too sure calling mutators on a proxy class really is that special, though.
...and I can't imagine there is a user who would seriously complain
It's not so special, but building a proxy reference that fully emulates the interface of the referenced value type is quite unusual. It's takes a lot of work, is very fragile and can't be done generically. that
pointer ptr ( i.operator->().operator->() );
gives an invalid pointer ;-).
Am I missing something ?
There was a guy who complained just last week on this very mailing list that putting an iterator_adaptor over a T const* suddenly produced writability in the iterator through operator-> !! http://lists.boost.org/MailArchives/boost-users/msg08656.php
Yeah, I (partially) read it to ensure I am not asking redundant questions before starting this thread. I still believe adapting pointers is a different story.
It's not such a different story. If I take a non-writable version your iterator, operating correctly, and wrap iterator_adaptor around it, it would be very strange if operator-> allowed you to mutate members.
Excursion: what's the proxy buying me ?
I use a generic, resizable container (similar to std::vector but with memory layout guarantees) to feed vector data to my graphics board through some rendering API. The proxy allows me to see a vector object instead of a reference to an array of floating type.
Operating on plain arrays in order to perform vector arithmetics is quite unhandy. Using a converting constructor from a reference to array type is a radical and error prone approach and would restrict me to use only one class for vector arithmetics (there is no way to tell if float[3] should be a homogenous 2D-vector or a non-homogenous 3D-vector, for example).
That's why I use a vector-reference proxy class that allows me to work on vectors whose data lives somewhere else.
I understand, thanks. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com