Topic: Questions about iterator library
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/06/23 Raw View
bparker@gil.com.au (Brian Parker) writes:
|> >(3) There's no mention of which operations are const. I would expect
|> >operator*() on an iterator to be const (it doesn't modify the iterator),
|> >but the CD is silent on this point.
|>
|> As long as an iterator fulfills the requirements, it shouldn't really
|> matter how the functions are implemented.
But the const-ness of a function is part of the interface, not the
implementation. Basically, what is being asked is, given:
void f( SomeContainer::iterator const& i ) ;
what operations can f do on i?
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ 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: bparker@gil.com.au (Brian Parker)
Date: 1997/06/24 Raw View
On 23 Jun 97 11:07:12 GMT, James Kanze
<james-albert.kanze@vx.cit.alcatel.fr> wrote:
>bparker@gil.com.au (Brian Parker) writes:
>
>|> >(3) There's no mention of which operations are const. I would expect
>|> >operator*() on an iterator to be const (it doesn't modify the iterator),
>|> >but the CD is silent on this point.
>|>
>|> As long as an iterator fulfills the requirements, it shouldn't really
>|> matter how the functions are implemented.
>
>But the const-ness of a function is part of the interface, not the
>implementation. Basically, what is being asked is, given:
>
> void f( SomeContainer::iterator const& i ) ;
>
>what operations can f do on i?
You're right- I suppose that constness should be specified.
It's not really an issue in the typical usage of iterators passed
by-value, but in a function such as f it would be. If the constness is
not specified in the standard then one would need to assume that the
iterator could be modified and hence only pass iterators by non-const
reference.
,Brian Parker (bparker@gil.com.au)
---
[ 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: Kresimir Fresl <fresl@grad.hr>
Date: 1997/06/19 Raw View
Kevin S. Van Horn wrote:
> I've been reading through the Dec. '96 CD, and I'm finding a few
> things in the iterator library rather puzzling:
...
> (2) For random iterators, it says that it[n] only needs to have a
> type convertible to T, rather than T&. This seems to imply that
> I can't count on
> a[n] = E;
> being legal.
...
[Few weeks ago I asked similar question both in c.s.c++ and
c.l.c++.mod., but there was no reply. Maybe we'll be more
lucky now.]
Here are few more notes on that subject:
Aforementioned requirement is in section 24.1, table 7,
`Random access iterator requirements (in addition to
bidirectional iterator)`, column `return type'. Same table
states that the `operational semantics' of `a[n]' is
`*(a + n)'.
`*a' is not mentioned in table 7, but in table 5, `Forward
iterator requirements' [and table 6 is, of course,
`Bidirectional iterator requirements (in addition to forward
iterator)'].
And in table 5, `return value' of `*a' is defined as `T&',
and it is also said: `If X is mutable, *a = t is valid'.
Now, what the term `operational semantics' really means?
Is it that `observable behaviour should be the same'?
Or something else?
On the other hand, if we can't write `a[n] = E', what is
the rationale behind that? Isn't this too severe restriction?
BTW, in the original HP STL documentation and in the
Musser & Saini's book return type of `*a' is defined as
`convertible to T', but with the additional requirement
`If X is mutable, *a = t is valid'.
fres
email: fresl@grad.hr
---
[ 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: bparker@gil.com.au (Brian Parker)
Date: 1997/06/20 Raw View
On 17 Jun 1997 09:28:11 PDT, "Kevin S. Van Horn"
<kevin.s.vanhorn@iname.com> wrote:
>I've been reading through the Dec. '96 CD, and I'm finding a few things in
>the iterator library rather puzzling:
>
>(1) The requirements for bidirectional iterators state that *it++ returns a
>value of type T& (T is the iterator's value type), but *it-- only needs to
>return a value convertible to T. Why the assymetry? This seems to say
>that
> T& foo = *it--
>isn't guaranteed to be legal.
>
>(2) For random iterators, it says that it[n] only needs to have a type
>convertible to T, rather than T&. This seems to imply that I can't count
>on
> a[n] = E;
>being legal.
>
That's got to be a bug in the draft. The latest SGI version of the STL
(at www.sgi.com) specifies that for an iterator x, *x returns a type
convertible to T to allow for a proxy implementation, but also
specifies that for mutable iterators the dereference assignment
expression *x = t is defined (output iterators are an exception). The
draft's current wording seems to have a mix of over-specifying (i.e.
specifying a return type of T for input iterator *a where it should be
"a type convertible to T") and under-specifying in that it doesn't
state that *x = t is required for mutable types.
I don't know what is on the committee's agenda, but hopefully these
bugs will be fixed.
>(3) There's no mention of which operations are const. I would expect
>operator*() on an iterator to be const (it doesn't modify the iterator),
>but the CD is silent on this point.
>
As long as an iterator fulfills the requirements, it shouldn't really
matter how the functions are implemented.
>(4) Why is the class forward_iterator_tag derived only from
>input_iterator_tag, and not also from output_iterator_tag? I thought that
>forward iterators were supposed to satisfy all the requirements of both
>input iterators and output iterators (along with a few more of their own).
I suppose to avoid the overhead of multiple inheritance amongst other
reasons- the tags are only used for compile-time function selection so
they need to be light-weight. In any case, I don't know that the
inheritance of tags is actually needed or used in the STL.
>
>(5) For the istream_iterator class template, operator*() is listed as
>returning a value of type const T &. But an istream_iterator is an input
>iterator, and earlier it states that operator*() for an input iterator
>should return a value of type T. This is an important difference: if
>operator*() returns a value of type T, then
> const T & x = *it; ++it;
>is a safe thing to do, where as if it returns a value of type const T &
>then the above is not safe, because the returned reference may be invalid
>after incrementing it.
>
>(6) The ctor for the ostream_iterator class takes a second argument "delim"
>of type const char *. Does the iterator make its own copy of this char
>array? Or is the caller required to leave this char array unmodified and
>undeleted for the lifetime of the ostream_iterator object constructed using
>it? Does the iterator take over ownership of the char array (being
>responsible for deleting it upon destruction)?
Good question. Typically one just uses a string literal and so it
doesn't matter in that case, but I agree it should be specified.
,Brian Parker (bparker@gil.com.au)
---
[ 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: "Kevin S. Van Horn" <kevin.s.vanhorn@iname.com>
Date: 1997/06/17 Raw View
I've been reading through the Dec. '96 CD, and I'm finding a few things in
the iterator library rather puzzling:
(1) The requirements for bidirectional iterators state that *it++ returns a
value of type T& (T is the iterator's value type), but *it-- only needs to
return a value convertible to T. Why the assymetry? This seems to say
that
T& foo = *it--
isn't guaranteed to be legal.
(2) For random iterators, it says that it[n] only needs to have a type
convertible to T, rather than T&. This seems to imply that I can't count
on
a[n] = E;
being legal.
(3) There's no mention of which operations are const. I would expect
operator*() on an iterator to be const (it doesn't modify the iterator),
but the CD is silent on this point.
(4) Why is the class forward_iterator_tag derived only from
input_iterator_tag, and not also from output_iterator_tag? I thought that
forward iterators were supposed to satisfy all the requirements of both
input iterators and output iterators (along with a few more of their own).
(5) For the istream_iterator class template, operator*() is listed as
returning a value of type const T &. But an istream_iterator is an input
iterator, and earlier it states that operator*() for an input iterator
should return a value of type T. This is an important difference: if
operator*() returns a value of type T, then
const T & x = *it; ++it;
is a safe thing to do, where as if it returns a value of type const T &
then the above is not safe, because the returned reference may be invalid
after incrementing it.
(6) The ctor for the ostream_iterator class takes a second argument "delim"
of type const char *. Does the iterator make its own copy of this char
array? Or is the caller required to leave this char array unmodified and
undeleted for the lifetime of the ostream_iterator object constructed using
it? Does the iterator take over ownership of the char array (being
responsible for deleting it upon destruction)?
(7) The istreambuf_iterator proxy class seems more elaborate than necessary
for istreambuf_iterator to fulfill the requirements of an an input
iterator. In particular, why is there a need to be able to construct an
istreambuf_iterator object from a proxy object? As far as I can tell, the
requirements for an input iterator would be satisfied if the proxy object
was merely a wrapper for a charT value, with operator*() returning this
encapsulated value, and no conversion from a proxy object to an
istreambuf_iterator object allowed.
---
[ 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
]