Boost logo

Boost Users :

From: David Abrahams (dave_at_[hidden])
Date: 2004-12-06 14:25:11


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.

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.

>>> ...and I can't imagine there is a user who would seriously complain
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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net