Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-02-20 11:41:59


Christian Engström <christian.engstrom_at_[hidden]> writes:

> David Abrahams wrote:
>> Christian Engström <christian.engstrom_at_[hidden]> writes:
>>>
>>>A proxy_iterator is publicly derived from the iterator of the
>>> underlying Container< proxy<T> >.
>> And if that iterator happens to be a pointer?
>>
> Then of course it doesn't work. But is the container really STL
> compliant if it has ordinary pointers as iterators?

Yes. Many std::vector implementations do that.

> If the answer to this question is yes, the requirement that the
> underlying iterator type must be a class should of course be added to
> the documentation, but apart from that I see no problem with it.
>
>>>Are we really allowed to define these operators like this? --Yes, we are.
>> No you're not. The standard makes it very clear that the semantics
>> of
>> an iterator's operator-> must correspond to those of its operator*.
>>
> Or else what?

Or else the class doesn't satisfy the iterator requirements.

> Is there anything particular that the standard says
> will break if the two operators have different semantics?

Technically, anything that claims to depend on a parameter matching
the iterator concept. Less, technically, any generic algorithm that
takes advantage of an iterator's operator->. The fact that the ones
in the standard library don't use operator-> doesn't mean very much,
since other peoples' algorithms are allowed to rely on iterators
matching the standard iterator requirements.

> In Bjarne Stroustrup's "The Design and Evolution of C++", he says on
> page 241 (in the edition that I have):
>
> "For ordinary pointers, use of -> is synonymous with some uses of
> unary * and []. For example, for a Y* p it holds that:
> p->m == (*p).m == p[0].m
> As usual, no such guarantee is provided for user-defined operator.
> The equivalence can be provided when desired: [...]"
>
> The way I read it, the phrase "can ... when desired" does not have the
> same meaning as "must always". Am I misunderstanding something or is
> Bjarne Stroustrup wrong?

Sure you can do whatever you want. You just can't call it an iterator
(in C++). The standard library defines what an iterator is.

>> The design makes several other wrong assumptions about iterator
>> requirements.
>>
> If you or somebody else can point them out to me I shall be very grateful.

I don't have time to look for all of them, but one assumption it
makes is that the underlying iterator supplies value_type,
iterator_category, etc. via nested public types as opposed to a
specialization of std::iterator_traits. Writing correct iterators is
really hard; that's part of the reason for the boost iterators
library.

>> indirect_iterator may already suit your needs.
>>
> Does indirect_iterator make possible to convert a program that has
> been written to use a direct container to use an indirect container
> instead by changing a single typedef?

Not by itself, but it does most of the work for you.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk