Topic: STL iterators implemented the wrong way ?


Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/10/08
Raw View
In article <533u4u$9a6@gap.cco.caltech.edu> dacut@ugcs.caltech.edu
(David A. Cuthbert) writes:

|> James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:
|> [regarding operator ->]
|> >It shall return *EITHER* a pointer to a class or union, *OR* an object
|> >(of class type).  There is nothing to disambiguate; both are legal (but
|> >things like int or int* are not).

|> Interesting.  If I have a vector<myclass *>::iterator i, then to call
|> a method of the object that i is really pointing to, that I could use
|> i->->mymethod()?  (I don't have access to a compiler that supports
|> overloading -> yet; hence why I'm asking).

|> For some reason, I figured that ->-> wouldn't be possible; it falls
|> into the "syntactically weird" category of things.

It's not possible.  The operator->() is a unary function; if a user
defined function is called, the -> will be applied to it, and so on,
until either a pointer to a class or union is returned, or something on
which operator-> is not legal.  There is, in this sense, an implicit
loop on operator-> (or, as I prefer to think of it, executing a user
operator-> does not "eat" the -> token).
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: dacut@ugcs.caltech.edu (David A. Cuthbert)
Date: 1996/10/09
Raw View
James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:
>In article <533u4u$9a6@gap.cco.caltech.edu> dacut@ugcs.caltech.edu
>(David A. Cuthbert) writes:
>|> Interesting.  If I have a vector<myclass *>::iterator i, then to call
>|> a method of the object that i is really pointing to, that I could use
>|> i->->mymethod()?  (I don't have access to a compiler that supports
>|> overloading -> yet; hence why I'm asking).

>It's not possible.  The operator->() is a unary function; if a user
>defined function is called, the -> will be applied to it, and so on,
>until either a pointer to a class or union is returned, or something on
>which operator-> is not legal.  There is, in this sense, an implicit
>loop on operator-> (or, as I prefer to think of it, executing a user
>operator-> does not "eat" the -> token).

I'm still a little confused here... how about an example?

Given
class myclass {
   public:
     void mymethod() { }
}

vector<myclass *>::iterator i = ...;


Okay, so (*i) returns a pointer to a myclass object.  To call mymethod()
on that object, I would use
   (*i)->mymethod();

To use the new syntax, it sounds like I would use
   i->mymethod();

So, the first iteration of -> returns a myclass * -- does it end at this
point?  That would cause problems, because now I have
   (myclass * something).mymethod();

which is invalid; I really want (myclass something).mymethod().

Obviously, I'm missing something.  Not to mention a compiler which supports
operator -> (gotta keep my priorities straight... rent, eat, then buy
a new compiler... :-)
--
David A. Cuthbert
dacut@ugcs.caltech.edu
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/10/10
Raw View
dacut@ugcs.caltech.edu (David A. Cuthbert) writes:

> James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:
> >In article <533u4u$9a6@gap.cco.caltech.edu> dacut@ugcs.caltech.edu
> >(David A. Cuthbert) writes:
> >|> Interesting.  If I have a vector<myclass *>::iterator i, then to call
> >|> a method of the object that i is really pointing to, that I could use
> >|> i->->mymethod()?  (I don't have access to a compiler that supports
> >|> overloading -> yet; hence why I'm asking).
>
> >It's not possible.  The operator->() is a unary function; if a user
> >defined function is called, the -> will be applied to it, and so on,
> >until either a pointer to a class or union is returned, or something on
> >which operator-> is not legal.  There is, in this sense, an implicit
> >loop on operator-> (or, as I prefer to think of it, executing a user
> >operator-> does not "eat" the -> token).
>
> I'm still a little confused here... how about an example?
>
> Given
> class myclass {
>    public:
>      void mymethod() { }
> }
>
> vector<myclass *>::iterator i = ...;
>
>
> Okay, so (*i) returns a pointer to a myclass object.  To call mymethod()
> on that object, I would use
>    (*i)->mymethod();
>
> To use the new syntax, it sounds like I would use
>    i->mymethod();

No, because vector<myclass*>::iterator::operator-> returns a myclass**.
This is neither a class type, a reference to class type nor a pointer to
class or union type.  So it is illegal.

On the other hand, with vector<myclass>, i->mymethod() is legal.  The
compiler first applies operator-> to the type of
vector<myclass>::iterator.  (In the case of vector, this is often simply
a myclass*, but we'll ignore this simplification for the moment.)  This
is a class type, which has an operator-> defined, so the compiler
generates a call to this function.  The compiler then reapplies the
operator-> to the results of the function.  This will probably be a
value of type myclass*, so the built-in operator-> will be used, and the
iteration (in the compiler) stops.

> So, the first iteration of -> returns a myclass * -- does it end at this
> point?

It ends before this, because the first iteration will return a myclass**.

The rules are really very simple and logical.  The compiler only looks
at what is to the right of the -> (call it x), and executes the
following algorithm:

    while ( typeof( x ) is class or reference to class
                                          with operator-> defined )
    {
        generate call to x::operator->
        replace x with results of call
    }
    if ( x is pointer to class or union )
        use built-in operator->
    else
        generate error

--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: bradds@concentric.net (Bradd W. Szonye)
Date: 1996/10/10
Raw View
David A. Cuthbert <dacut@ugcs.caltech.edu> wrote in article
<53f8k2$p3e@gap.cco.caltech.edu>...
> I'm still a little confused here... how about an example?
>
> Given
> class myclass {
>    public:
>      void mymethod() { }
> }
>
> vector<myclass *>::iterator i = ...;
>
> Okay, so (*i) returns a pointer to a myclass object.  To call mymethod()
> on that object, I would use
>    (*i)->mymethod();

No, to call mymethod on that object, you'd use

 (*i).mymethod();

or

 i->mymethod();

which are always equivalent for the built-in operator->().

> To use the new syntax, it sounds like I would use
>    i->mymethod();

Correct.

> So, the first iteration of -> returns a myclass * -- does it end at this
> point?

Correct.

That would cause problems, because now I have
>    (myclass * something).mymethod();
> which is invalid; I really want (myclass something).mymethod().

Incorrect.

At that point, you have (myclass* something)->mymethod(). That's what's
meant by operator->() being iterative or recursive. You keep applying
operator-> on the returned object (if any) until it returns a pointer; then
the language applies the built-in operator-> on that pointer.

Therefore, given,

 iterator2 iterator1::operator->();
 iterator3 iterator2::operator->();
 myclass* iterator3::operator->();

the syntax

 iterator1 i;
 i->mymethod();

is roughly equivalent to

 iterator1 i;
 iterator2 __t1(i.operator->());
 iterator3 __t2(__t1.operator->());
 myclass* __t3(__t2.operator->());
 __t3->mymethod();

which is what you want.
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~bradds
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: dacut@ugcs.caltech.edu (David A. Cuthbert)
Date: 1996/10/13
Raw View
Bradd W. Szonye <bradds@concentric.net> wrote:
>David A. Cuthbert <dacut@ugcs.caltech.edu> wrote in article
>> vector<myclass *>::iterator i = ...;
>>
>> Okay, so (*i) returns a pointer to a myclass object.  To call mymethod()
>> on that object, I would use
>>    (*i)->mymethod();

>No, to call mymethod on that object, you'd use
>
> (*i).mymethod();

Hmm.. my compiler (BC++4.52) disagrees.  The following:
----
class A { public: void msg(void) const { cout << "msg() called." << endl; } };

int main(void)
{
     vector<A *>  p;
     A            a;
     p.push_back(&a);

     vector<A *>::iterator i = p.begin();
     (*i).msg();

     return 0;
}
----
fails to compile, complaining with "Structure required on left side of
. or .*".  Is this a problem with my compiler?  (I don't think it is;
really, (*i) should return an A *.  (A *).method() doesn't make sense).
Changing the offending line to (*i)->msg() compiles properly.

>or
>
> i->mymethod();

This causes BC++ to complain about a pointer to a structure required
on the left side of ->; not surprising, since I'm using the HP version
of the STL (which doesn't define -> for whatever reason).

Is this an environment-specific problem?

[another example deleted for brevity]
>At that point, you have (myclass* something)->mymethod(). That's what's
>meant by operator->() being iterative or recursive. You keep applying
>operator-> on the returned object (if any) until it returns a pointer; then
>the language applies the built-in operator-> on that pointer.

Ah.  The last sentence clarifies things greatly!  :-)  From all the
discussion, it sounded like the last call to *any* -> could occur when
a -> returned a class pointer; then .method would be called.
--
David A. Cuthbert
dacut@ugcs.caltech.edu


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bradds@concentric.net (Bradd W. Szonye)
Date: 1996/10/14
Raw View
David A. Cuthbert <dacut@ugcs.caltech.edu> wrote in article
<53opfj$8d7@gap.cco.caltech.edu>...
> Bradd W. Szonye <bradds@concentric.net> wrote:
> >No, to call mymethod on that object, you'd use
> > (*i).mymethod();
> Hmm.. my compiler (BC++4.52) disagrees.  The following:

Sorry, I goofed a bit. For a container<T*>, there's an extra level of
indirection that I missed, namely that the container element type is also a
pointer. That restricts the range of iterator methods you can use, namely
to

 (**i).mymethod();
 (*i)->mymethod();

That is, you need to 'dereference' the iterator to get a T*, and then you
can use (*x).member or x->member syntax on the result. The reason that you
can't use -> directly for such an iterator is that -> is not a valid
operation on a T**, which is conceptually what an 'iterator over T*s' is.

> Ah.  The last sentence clarifies things greatly!  :-)  From all the
> discussion, it sounded like the last call to *any* -> could occur when
> a -> returned a class pointer; then .method would be called.

Glad I could help.
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~bradds


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/10/14
Raw View
dacut@ugcs.caltech.edu (David A. Cuthbert) writes:

> Bradd W. Szonye <bradds@concentric.net> wrote:
> >David A. Cuthbert <dacut@ugcs.caltech.edu> wrote in article
> >> vector<myclass *>::iterator i = ...;
> >>
> >> Okay, so (*i) returns a pointer to a myclass object.  To call mymethod()
> >> on that object, I would use
> >>    (*i)->mymethod();
>
> >No, to call mymethod on that object, you'd use
> >
> > (*i).mymethod();
>
> Hmm.. my compiler (BC++4.52) disagrees.  The following:
> ----
> class A { public: void msg(void) const { cout << "msg() called." << endl; } };
>
> int main(void)
> {
>      vector<A *>  p;
              ^^^

Note: this is a vector of pointers!

>      A            a;
>      p.push_back(&a);
>
>      vector<A *>::iterator i = p.begin();
>      (*i).msg();
>
>      return 0;
> }
> ----
> fails to compile, complaining with "Structure required on left side of
> . or .*".  Is this a problem with my compiler?  (I don't think it is;
> really, (*i) should return an A *.  (A *).method() doesn't make sense).
> Changing the offending line to (*i)->msg() compiles properly.

Correct.  It all depends on what is in the vector.  Generally, if the
vector contains objects, i->msg() would be correct, if it contains
pointers to the objects, (*i)->msg() is the answer.

> >or
> >
> > i->mymethod();
>
> This causes BC++ to complain about a pointer to a structure required
> on the left side of ->; not surprising, since I'm using the HP version
> of the STL (which doesn't define -> for whatever reason).

The HP version of STL doesn't define operator-> because this would lead
to an error on most compilers if the vector did NOT contain objects of
class or union type.  The draft standard has since clarified that this
should not cause a problem, but many compilers still would not compile
it otherwise.

> Is this an environment-specific problem?

For the moment, yes.

--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: jpotter@falcon.lhup.edu (John E. Potter)
Date: 1996/10/14
Raw View
David A. Cuthbert (dacut@ugcs.caltech.edu) wrote:

: Obviously, I'm missing something.  Not to mention a compiler which supports
: operator -> (gotta keep my priorities straight... rent, eat, then buy
: a new compiler... :-)

operator->() was introduced in 1986 and was supported by cfront2.0.  The
following may help to show its workings.  This compiles on Borland3.1
DOS 286.  It is an expansion of an example in D&E 11.5 which explains
it much better than I could.

#include <iostream.h>
struct PI {
 int* p;
// int* operator-> () { return p; }  // not allowed but g++ accepts
// int& operator-> () { return *p; } // not allowed but g++ accepts
 int& operator* () { return *p; }
 };
struct S {
 int s;
 };
struct PS {
 S* p;
 S* operator-> () { return p; }
 S& operator* () { return *p; }
 };
struct PPS {
 PS* pp;
 PS& operator-> () { return *pp; }
 PS& operator* () { return *pp; }
 };
int main () {
 int i = { 5 };
 PI pi = { &i };
 S s = { 5 };
 PS ps = { &s };
 PPS pps = { &ps };
 cout
  << (*pi == i)
//  << (*(pi.operator->()) == i) // g++ accepts
//  << (pi.operator->() == i)    // g++ accepts
  << ((*ps).s == s.s)
  << (ps->s == s.s)
  << ((**pps).s == s.s)
  << ((*pps)->s == s.s)
  << (pps->s == s.s)
  << endl;
 return 0;
 }

Operator-> applied to a class object or reference is the class defined
operator, but when applied to a pointer, it is the global operator.
Note the difference in return type for the four operator->() functions.
The most obvious use is in PS where a pointer to class object is returned.
If the standard library iterators supported operator-> in this form,
many of todays compilers would not allow vector<int> because they
would instantiate the invalid operator even though it was never used.

The discussion of new rules involves templates with operator->() not
its semantics.  Forced instantiations and specializations should be
allowed in the presence of an invalid operator-> as long as it is
not used.

HTH,
John
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: tony@online.tmx.com.au (Tony Cook)
Date: 1996/10/03
Raw View
Gary Brown (gbrown@thebrowns.ultranet.com) wrote:
: Colon,

: >> 2. "operator-> shall return either a pointer to a class or an object"

: Would you disambiguate?  Is that mean return an object or a pointer to
: an object?

operator->() can return either.

If it returns an object then that object should also supply an
operator->() (which is then applied).

If it returns a pointer then the built-in operator is applied.

Basically operator->() is recursively applied until a pointer to an
object is returned.

--
        Tony Cook - tony@online.tmx.com.au
                    100237.3425@compuserve.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: dacut@ugcs.caltech.edu (David A. Cuthbert)
Date: 1996/10/05
Raw View
James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:
[regarding operator ->]
>It shall return *EITHER* a pointer to a class or union, *OR* an object
>(of class type).  There is nothing to disambiguate; both are legal (but
>things like int or int* are not).

Interesting.  If I have a vector<myclass *>::iterator i, then to call
a method of the object that i is really pointing to, that I could use
i->->mymethod()?  (I don't have access to a compiler that supports
overloading -> yet; hence why I'm asking).

For some reason, I figured that ->-> wouldn't be possible; it falls
into the "syntactically weird" category of things.
--
David A. Cuthbert
dacut@ugcs.caltech.edu


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/10/01
Raw View
In article <324C9FE0.64B8@thebrowns.ultranet.com> Gary Brown
<gbrown@thebrowns.ultranet.com> writes:

|> >> 2. "operator-> shall return either a pointer to a class or an object"

|> Would you disambiguate?  Is that mean return an object or a pointer to
|> an object?

It shall return *EITHER* a pointer to a class or union, *OR* an object
(of class type).  There is nothing to disambiguate; both are legal (but
things like int or int* are not).
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: danm@zipnet.net (Dan Muller)
Date: 1996/09/26
Raw View
Ronny Bremer <rbremer@future-gate.com> wrote:


>According to the April working paper and all documentation I've found on
>the web, the iterator acts like a C++ pointer.
>Of course, there are a couple of differences, for instance,
>if i == j the following
>i++ == j++ does not need to be TRUE.

This is specifically for input iterators, which are only one category of
iterators.

>Now, most of the algorithms provided by STL (I'll take find as an
>example) are getting their parameters by value, e.q.

>template <class iterator, class T>
>iterator find(iterator begin, iterator end, T& Value)

>That means, the iterators begin and end are created via the copy
>constructor.

Yes. So?

>Now consider the following code:

>main()
>{
>   vector<int> intVector;

>   intVector.push_back(1);
>   intVector.push_back(2);
>   intVector.push_back(3);

>   vector<int>::iterator it1(intVector);
>   vector<int>::iterator it2(intVector);

>   it1 = find(intVector.begin(), intVector.end(), 2);
>   if (it1 != intVector.end())
>   {
>      cout << "got it" << endl;
>      cout << "now searching the rest of intVector for 3" << endl;
>      it2 = find(it1, intVector.end(), 3);
>      if (it2 != intVector.end())
>      {
>         cout << "3 was found" << endl;
>      } else {
>         cout << "sorry" << endl;
>      }
>   }
>}

>Find is using operator++ to advance the iterator begin. Because there is
>no guarantee that it1++ == it2++ (if it1 == it2) the following could
>happen:

>output A:
>got it
>now searching the rest of intVector for 3
>3 was found

>output B:
>got it
>now searching the rest of intVector for 3
>sorry

>In case A the first find got the values 1 and 2 and returned with the
>iterator pointing to 2. Then, of course, the next find can still get the
>value 3.
>In case B the first find got the values 3, 1 and 2 and returned with the
>iterator pointing to 2. In that case, the second iterator will find
>nothing.

>Of course, with the vector template it will never fail, because the
>iterator of vector is a simple pointer. But what happens if the vector
>is allocated within an object oriented database ????

>Please, now go ahead and knock on my head, I want to know what is wrong.

There is nothing wrong. The STL system very carefully defines different
categories of iterators. The behavior that seems to be bothering you here is
specific to input iterators. Input and output iterators are the least flexible
categories of iterators, and have only a few of the characteristics of pointers.
Vector iterators are bidirectional iterators (from memory - is that right?) and
are therefore more capable.

Algorithms like find that are specified as requiring input iterators for
arguments just need iterators that have *at least* the characteristics of input
iterators, and will work just fine with iterators of any category other than
"output iterator".

When working with iterators, and especially when writing your own, you must be
very careful and explicit about what category of iterator you're working with,
and not make demands of an iterator that it can't satisfy. When designing your
own iterators, you typically have to trade off flexibility for dificulty of
implementation and/or efficiency. E.g., I wrote several input iterator classes
for dealing with streams of data coming from a network service; the iterators
make a nice handle for accessing a stream, and sticking to input iterator
semantics keeps the implementation simple and encourages (actually, requires)
one-pass use of the iterators, which is the most efficient way to deal with data
coming over the net.


--
Dan Muller
danm@zipnet.net



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Chelly Green <chelly@eden.com>
Date: 1996/09/26
Raw View
Colin Rafferty wrote:
>
> Sean L Palmer writes:
>
> > I don't see why they don't add operator ->()'s to iterators, and would
> > appreciate it if someone would tell me why this is so.
>
> Two different reasons:
>
> 1. You can implement operator-> using operator*, but not vice-versa.
>    Classes should be minimal and complete [Meyers92, Item 18].

How can you implement the operator outside the class? Heck, if it can be
minimal, just provide an accessor to the pointer  :-)

    template<class T>
    class SmartPointer {
    public:
        // ...
        T* pointer() const;
    };

usage

    void f( SmartPointer<Foo> p )
    {
        p.pointer()->i = 10;
    }

Kinda tedious, huh? Hey, the user can derive all the operations
necessary, right?

> 2. "operator-> shall return either a pointer to a class or an object"
>    [over.ref.1], so having operator-> in an iterator would stop you from
>    iterating over collections of any fundamental type.

Well, I took the time to look it up in a draft standard, and it
specifically mentions that operator -> in a template is allowed to
return a type that does not fit the above, as long as it is never
called, etc.

--
  14.3.3  Instantiation of operator->                       [temp.opref]

1 If a template class has an operator->,  that  operator->  can  have  a
  return  type  that cannot be dereferenced by -> as long as that opera-
  tor-> is neither invoked, nor has its address  taken,  isn't  virtual,
  nor is explicitly instantiated.  [Example:
          template<class T> class Ptr {
                  // ...
                  T* operator->();
          };

          Ptr<int> pi; // ok
          Ptr<Rec> pr; // ok

          void f()
          {
                  pi->m = 7; // error: Ptr<int>::operator->() returns a
type
                             //        that cannot be dereference by ->
                  pr->m = 7; // ok if Rec has an accessible member m
                             // of suitable type
          }
   --end example]
--

I always thought like you did, that you could get the effect with
(*p).f, but that is inconvenient, and the above rule is obviously made
to allow operator ->, yet still work with built-in types.

...

--
Chelly Green | mailto:chelly@eden.com | http://www.eden.com/~chelly


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Gary Brown <gbrown@thebrowns.ultranet.com>
Date: 1996/09/28
Raw View
Colon,

>> 2. "operator-> shall return either a pointer to a class or an object"

Would you disambiguate?  Is that mean return an object or a pointer to
an object?

Thanks,
Gary


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Colin Rafferty <craffert@spssunp.spspme.ml.com>
Date: 1996/09/24
Raw View
Sean L Palmer writes:

> I don't see why they don't add operator ->()'s to iterators, and would
> appreciate it if someone would tell me why this is so.

Two different reasons:

1. You can implement operator-> using operator*, but not vice-versa.
   Classes should be minimal and complete [Meyers92, Item 18].

2. "operator-> shall return either a pointer to a class or an object"
   [over.ref.1], so having operator-> in an iterator would stop you from
   iterating over collections of any fundamental type.

--
This posting adheres to the SELF-DISCIPLINE guidelines for better
USENET discussions. See http://www.eiffel.com/discipline.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/09/24
Raw View
In article <01bba689$51cf6fa0$0a2920cc@landspeeder.delta.com>
sean@delta.com (Sean L. Palmer) writes:

|> > According to the April working paper and all documentation I've found on
|> > the web, the iterator acts like a C++ pointer.
|> > Of course, there are a couple of differences, for instance,
|> > if i == j the following
|> > i++ == j++ does not need to be TRUE.

|> I think the major problem with iterators is that they're not required to
|> provide an
|> operator ->(), which prohibits using many functions written for pointers to
|> be used on otherwise compatible stl containers.

An iterator is not required to provide operator->() because it is not
used in the library.  It is also not reasonable to require it of all
iterators (for example, the iostream iterators).  On the other hand, I
think that all of the normal iterators in the library do provided it,
and I would expect it to be provided by user defined iterators where
reasonable.

Of course, none of the current implementations provide it, because if
they did, you could not instantiate the iterator for non-class types
with current compilers.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/09/25
Raw View
In article <ocrg2492hvk.fsf@spssunp.spspme.ml.com> Colin Rafferty
<craffert@spssunp.spspme.ml.com> writes:

|> Sean L Palmer writes:

|> > I don't see why they don't add operator ->()'s to iterators, and would
|> > appreciate it if someone would tell me why this is so.

|> Two different reasons:

|> 1. You can implement operator-> using operator*, but not vice-versa.
|>    Classes should be minimal and complete [Meyers92, Item 18].

I think I would argue that a class simulating a pointer is not complete
if it does *NOT* offer operator->().  Since you site Meyers, it is worth
noting that his reference counted pointer class, for example, has an
operator->.

|> 2. "operator-> shall return either a pointer to a class or an object"
|>    [over.ref.1], so having operator-> in an iterator would stop you from
|>    iterating over collections of any fundamental type.

But it says elsewhere that this shall be checked *only* if the
operator-> is actually instantiated.  So as long as I don't use it, I
should be OK.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Matt Austern <austern@sgi.com>
Date: 1996/09/19
Raw View
Ronny Bremer <rbremer@future-gate.com> writes:

> According to the April working paper and all documentation I've found on
> the web, the iterator acts like a C++ pointer.
> Of course, there are a couple of differences, for instance,
> if i == j the following
> i++ == j++ does not need to be TRUE.

...

> Find is using operator++ to advance the iterator begin. Because there is
> no guarantee that it1++ == it2++ (if it1 == it2) the following could
> happen:

There are different kinds of iterators; see section 24.1
[lib.iterator.requirements] of the draft standard.  Input iterators do
not guarantee that i == j implies i++ == j++.  Other kinds of
iterators, however (forward iterators, bidirectional iterators, and
random access iterators) do guarantee that.

Note that each STL algorithm in clause 25 specifies what sort of
iterator its arguments must be.  Algorithms that use forward iterators
do so precisely because they require guarantees that input iterators
don't provide.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Graham C. Hughes" <graham@resnet.ucsb.edu>
Date: 1996/09/19
Raw View
-----BEGIN PGP SIGNED MESSAGE-----

Ronny Bremer <rbremer@future-gate.com> writes:

> According to the April working paper and all documentation I've found on
> the web, the iterator acts like a C++ pointer.
> Of course, there are a couple of differences, for instance,
> if i == j the following
> i++ == j++ does not need to be TRUE.

Not really.  This is only a requirement for input iterators.
Everything from forward iterators on does this quite nicely.

All of the built-in containers give you at least bidirectional
iterators; the only thing that uses just input/output iterators are
the streaming classes.

> Find is using operator++ to advance the iterator begin. Because there is
> no guarantee that it1++ == it2++ (if it1 == it2) the following could
> happen:

<possible divergent output snipped>

Again, because you're using a vector, you get random access iterators
for free.  This is guaranteed by STL, BTW.  Therefore, the finds will
work as you expect them to.

> Please, now go ahead and knock on my head, I want to know what is
> wrong.

What's wrong is that you forgot there are several classes of
iterators.  If you do much more work with STL, I can recommend Musser
and Saini's _STL_Tutorial_and_Reference_Guide_, which is a pretty
reasonable both.
- --
Graham Hughes (graham@resnet.ucsb.edu)  finger for PGP key
``Unix is many things to many people, but it's never been
  everything to anybody.''
Home page at: http://www.cs.ucsb.edu/~ghughes/

-----BEGIN PGP SIGNATURE-----
Version: 2.6.2
Comment: Processed by Mailcrypt 3.4, an Emacs/PGP interface

iQCVAwUBMkG5qiqNPSINiVE5AQHFgAP/X8mERo2nBFYkfPn8VoXRx5OeBJtLOr56
EYQ/6CfH2AajZRyNhLfXhXgOyelwXj9KgeDfWtuFpHGdnZdFjnoae5pPPEl11XGy
ABgJEO270xsjh/+HOZBsaojUjyO+lG7xcViT1bZZvOX6pjzsCo8S+wgf/ojiZ+l1
cqopVw2qqsA=
=xD2G
-----END PGP SIGNATURE-----


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: sean@delta.com (Sean L. Palmer)
Date: 1996/09/20
Raw View
> According to the April working paper and all documentation I've found on
> the web, the iterator acts like a C++ pointer.
> Of course, there are a couple of differences, for instance,
> if i == j the following
> i++ == j++ does not need to be TRUE.

I think the major problem with iterators is that they're not required to
provide an
operator ->(), which prohibits using many functions written for pointers to
be used on otherwise compatible stl containers.

Making them provide operator -> would require adding two versions of it to
each iterator (one for const access, one for non-const access), which is
insignificant compared to the size of STL as it now stands, and is
essentially the same code you'd use for operator *, which they ARE required
to provide.

I don't see why they don't add operator ->()'s to iterators, and would
appreciate it if someone would tell me why this is so.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Ronny Bremer <rbremer@future-gate.com>
Date: 1996/09/20
Raw View
Matt Austern wrote:
>
> There are different kinds of iterators; see section 24.1
> [lib.iterator.requirements] of the draft standard.  Input iterators do
> not guarantee that i == j implies i++ == j++.  Other kinds of
> iterators, however (forward iterators, bidirectional iterators, and
> random access iterators) do guarantee that.

True. I was talking about input iterators only, because I need to
created my own iterator but it can only be an input iterator (see my
question in comp.lang.c++.moderated).

> Note that each STL algorithm in clause 25 specifies what sort of
> iterator its arguments must be.  Algorithms that use forward iterators
> do so precisely because they require guarantees that input iterators
> don't provide.

I've take a look at it. I want to use some algorithms of STL for my own
iterators but now I have to recheck if those algorithms can work with
input iterators.

Thanks.

Ronny
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Pete Becker <pbecker@oec.com>
Date: 1996/09/20
Raw View
Sean L. Palmer wrote:
>
> > According to the April working paper and all documentation I've found on
> > the web, the iterator acts like a C++ pointer.
> > Of course, there are a couple of differences, for instance,
> > if i == j the following
> > i++ == j++ does not need to be TRUE.
>
> I think the major problem with iterators is that they're not required to
> provide an
> operator ->(), which prohibits using many functions written for pointers to
> be used on otherwise compatible stl containers.

"Prohibits" is far too strong a word. "Makes somewhat less convenient"
would be better. After all, you can always use (*iter).foo();

>
> Making them provide operator -> would require adding two versions of it to
> each iterator (one for const access, one for non-const access), which is
> insignificant compared to the size of STL as it now stands, and is
> essentially the same code you'd use for operator *, which they ARE required
> to provide.
>
> I don't see why they don't add operator ->()'s to iterators, and would
> appreciate it if someone would tell me why this is so.
> ---
> [ comp.std.c++ is moderated.  To submit articles: Try just posting with your
>                 newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
>   comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
>   Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
>   Comments? mailto:std-c++-request@ncar.ucar.edu
> ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Poul Thomas Lomholt" <davinci@image.dk>
Date: 1996/09/21
Raw View
Ronny Bremer <rbremer@future-gate.com> wrote in article
<m0v3QSP-0007ZeC@fgsco01.Future-Gate.com>...
> Hi C++ experts,
>
> the subject might seem very strong. I'm not sure if my thoughts are
> correct.
> I'ld realy love to get some reply either by email or by news, because I
> want to implement a couple of iterator classes on my own but don't know
> if I'm doing the right thing (please refer to my next mail).
>
> Now to the subject.
>
> According to the April working paper and all documentation I've found on
> the web, the iterator acts like a C++ pointer.
> Of course, there are a couple of differences, for instance,
> if i == j the following
> i++ == j++ does not need to be TRUE.
>
> Now, most of the algorithms provided by STL (I'll take find as an
> example) are getting their parameters by value, e.q.
>
> template <class iterator, class T>
> iterator find(iterator begin, iterator end, T& Value)
>
> That means, the iterators begin and end are created via the copy
> constructor.

Yes, but that does not seem to be the problem!

>
> Now consider the following code:
>
> main()
> {
>    vector<int> intVector;
>
>    intVector.push_back(1);
>    intVector.push_back(2);
>    intVector.push_back(3);
>
>    vector<int>::iterator it1(intVector);
>    vector<int>::iterator it2(intVector);
>
>    it1 = find(intVector.begin(), intVector.end(), 2);
>    if (it1 != intVector.end())
>    {
>       cout << "got it" << endl;
>       cout << "now searching the rest of intVector for 3" << endl;
>       it2 = find(it1, intVector.end(), 3);
>       if (it2 != intVector.end())
>       {
>          cout << "3 was found" << endl;
>       } else {
>          cout << "sorry" << endl;
>       }
>    }
> }
>
> Find is using operator++ to advance the iterator begin. Because there is
> no guarantee that it1++ == it2++ (if it1 == it2) the following could
> happen:
>
> output A:
> got it
> now searching the rest of intVector for 3
> 3 was found
>
> output B:
> got it
> now searching the rest of intVector for 3
> sorry
>
> In case A the first find got the values 1 and 2 and returned with the
> iterator pointing to 2. Then, of course, the next find can still get the
> value 3.
> In case B the first find got the values 3, 1 and 2 and returned with the
> iterator pointing to 2. In that case, the second iterator will find
> nothing.
>
> Of course, with the vector template it will never fail, because the
> iterator of vector is a simple pointer. But what happens if the vector
> is allocated within an object oriented database ????

The key fact is that a vector is an ORDERED collection, that is, you know
that the
container guarantees that the order is 1,2,3. Thats why the vector has
push_back and
push_front inserters. A database on the other hand does not need to
guarantee the ordering,
and it would probably never have the push_xx functions but only a plain
insert function. In you
example you should not use it2 to be the starting point of the next find.

>
> Please, now go ahead and knock on my head, I want to know what is wrong.
>
> Thanks in advance.
>
> Ronny

HTH
Poul Thomas Lomholt

> ---
> [ comp.std.c++ is moderated.  To submit articles: Try just posting with
your
>                 newsreader.  If that fails, use
mailto:std-c++@ncar.ucar.edu
>   comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
>   Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
>   Comments? mailto:std-c++-request@ncar.ucar.edu
> ]
>
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Ronny Bremer <rbremer@future-gate.com>
Date: 1996/09/21
Raw View
I've checked the standard draft again. Those functions I'ld like to use
(for_each, find,..) are taking inputiterators as parameters.

So, I believe, my questions still applies.

Regards,

Ronny
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Ronny Bremer <rbremer@future-gate.com>
Date: 1996/09/21
Raw View
Reposting article removed by rogue canceller.

I've checked the standard draft again. Those functions I'ld like to use
(for_each, find,..) are taking inputiterators as parameters.

So, I believe, my questions still applies.

Regards,

Ronny
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Poul Thomas Lomholt" <davinci@image.dk>
Date: 1996/09/21
Raw View
Reposting article removed by rogue canceller.

Ronny Bremer <rbremer@future-gate.com> wrote in article
<m0v3QSP-0007ZeC@fgsco01.Future-Gate.com>...
> Hi C++ experts,
>
> the subject might seem very strong. I'm not sure if my thoughts are
> correct.
> I'ld realy love to get some reply either by email or by news, because I
> want to implement a couple of iterator classes on my own but don't know
> if I'm doing the right thing (please refer to my next mail).
>
> Now to the subject.
>
> According to the April working paper and all documentation I've found on
> the web, the iterator acts like a C++ pointer.
> Of course, there are a couple of differences, for instance,
> if i == j the following
> i++ == j++ does not need to be TRUE.
>
> Now, most of the algorithms provided by STL (I'll take find as an
> example) are getting their parameters by value, e.q.
>
> template <class iterator, class T>
> iterator find(iterator begin, iterator end, T& Value)
>
> That means, the iterators begin and end are created via the copy
> constructor.

Yes, but that does not seem to be the problem!

>
> Now consider the following code:
>
> main()
> {
>    vector<int> intVector;
>
>    intVector.push_back(1);
>    intVector.push_back(2);
>    intVector.push_back(3);
>
>    vector<int>::iterator it1(intVector);
>    vector<int>::iterator it2(intVector);
>
>    it1 = find(intVector.begin(), intVector.end(), 2);
>    if (it1 != intVector.end())
>    {
>       cout << "got it" << endl;
>       cout << "now searching the rest of intVector for 3" << endl;
>       it2 = find(it1, intVector.end(), 3);
>       if (it2 != intVector.end())
>       {
>          cout << "3 was found" << endl;
>       } else {
>          cout << "sorry" << endl;
>       }
>    }
> }
>
> Find is using operator++ to advance the iterator begin. Because there is
> no guarantee that it1++ == it2++ (if it1 == it2) the following could
> happen:
>
> output A:
> got it
> now searching the rest of intVector for 3
> 3 was found
>
> output B:
> got it
> now searching the rest of intVector for 3
> sorry
>
> In case A the first find got the values 1 and 2 and returned with the
> iterator pointing to 2. Then, of course, the next find can still get the
> value 3.
> In case B the first find got the values 3, 1 and 2 and returned with the
> iterator pointing to 2. In that case, the second iterator will find
> nothing.
>
> Of course, with the vector template it will never fail, because the
> iterator of vector is a simple pointer. But what happens if the vector
> is allocated within an object oriented database ????

The key fact is that a vector is an ORDERED collection, that is, you know
that the
container guarantees that the order is 1,2,3. Thats why the vector has
push_back and
push_front inserters. A database on the other hand does not need to
guarantee the ordering,
and it would probably never have the push_xx functions but only a plain
insert function. In you
example you should not use it2 to be the starting point of the next find.

>
> Please, now go ahead and knock on my head, I want to know what is wrong.
>
> Thanks in advance.
>
> Ronny

HTH
Poul Thomas Lomholt

> ---
> [ comp.std.c++ is moderated.  To submit articles: Try just posting with
your
>                 newsreader.  If that fails, use
mailto:std-c++@ncar.ucar.edu
>   comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
>   Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
>   Comments? mailto:std-c++-request@ncar.ucar.edu
> ]
>
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Ronny Bremer <rbremer@future-gate.com>
Date: 1996/09/19
Raw View
Hi C++ experts,

the subject might seem very strong. I'm not sure if my thoughts are
correct.
I'ld realy love to get some reply either by email or by news, because I
want to implement a couple of iterator classes on my own but don't know
if I'm doing the right thing (please refer to my next mail).

Now to the subject.

According to the April working paper and all documentation I've found on
the web, the iterator acts like a C++ pointer.
Of course, there are a couple of differences, for instance,
if i == j the following
i++ == j++ does not need to be TRUE.

Now, most of the algorithms provided by STL (I'll take find as an
example) are getting their parameters by value, e.q.

template <class iterator, class T>
iterator find(iterator begin, iterator end, T& Value)

That means, the iterators begin and end are created via the copy
constructor.

Now consider the following code:

main()
{
   vector<int> intVector;

   intVector.push_back(1);
   intVector.push_back(2);
   intVector.push_back(3);

   vector<int>::iterator it1(intVector);
   vector<int>::iterator it2(intVector);

   it1 = find(intVector.begin(), intVector.end(), 2);
   if (it1 != intVector.end())
   {
      cout << "got it" << endl;
      cout << "now searching the rest of intVector for 3" << endl;
      it2 = find(it1, intVector.end(), 3);
      if (it2 != intVector.end())
      {
         cout << "3 was found" << endl;
      } else {
         cout << "sorry" << endl;
      }
   }
}

Find is using operator++ to advance the iterator begin. Because there is
no guarantee that it1++ == it2++ (if it1 == it2) the following could
happen:

output A:
got it
now searching the rest of intVector for 3
3 was found

output B:
got it
now searching the rest of intVector for 3
sorry

In case A the first find got the values 1 and 2 and returned with the
iterator pointing to 2. Then, of course, the next find can still get the
value 3.
In case B the first find got the values 3, 1 and 2 and returned with the
iterator pointing to 2. In that case, the second iterator will find
nothing.

Of course, with the vector template it will never fail, because the
iterator of vector is a simple pointer. But what happens if the vector
is allocated within an object oriented database ????

Please, now go ahead and knock on my head, I want to know what is wrong.

Thanks in advance.

Ronny
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]