Topic: =?iso-8859-15?q?Re:_Problems_interpreting_requirement_for_std::?=


Author: gcc@integrable-solutions.net (Gabriel Dos Reis)
Date: Wed, 14 Sep 2005 14:30:14 GMT
Raw View
AlbertoBarbati@libero.it (Alberto Ganesh Barbati) writes:

| > And James' claim that the l.end() is invalidated is bogus.
| >
| > | The value which is passed as
| > | the "last" parameter remains a valid iterator which keeps pointing to
| > | the same element for the whole execution of the algorithm. Therefore the
| > | statement will effectively just append a entire copy of l at the end of
| > | l itself.
| >
| > Consider this:
| >
| >     p = l.end();
| >     l.push_back(8);
| >     q = l.end();
| >     assert (p == q);
| >
|
| That might happen for some (probably most) implementations of std::list,

I'm not talking of a particular implementation artifact.  The
assertion is based on the semantics of insert().

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gcc@integrable-solutions.net (Gabriel Dos Reis)
Date: Tue, 13 Sep 2005 04:20:31 GMT
Raw View
squell@alumina.nl (Marc Schoolderman) writes:

| kanze wrote:
|
| > Finally, what about something like:
| >     copy( l.begin(), l.end(), back_inserter( l ) ) ;
| > I think that, realistically, this will generally result in an
| > endless loop.  And yet, it requires quite a stretch of the
| > imagination to say that back_inserter( l ) is in the range of
| > [l.begin(),l.end()).
|
| I think this example is different from the others, since the input and

Indeed, this example -- which I originally posted to
news:fr.comp.lang.c++ -- is fundamentally different from the
vector::iterator case.

In the vector::iterator, it is not hard to offer a definition of
"overlap" that meets common sense such that the assumptions made by
std::copy is violated.

| output ranges don't strictly overlap, yet assigning through the output
| iterator has the side effect of increasing the input range.

Right, that is the crux of the issue.  Furthermore, back_inserter(l)
does not even belond to the same category as the input.

| This also
| means the complexity requirement of copy() gets violated since it will
| do more than "exactly last - first assignments" -- unless it measures
| "last - first" before it enteres the copy loop, but that would be
| inefficient for bidirectional iterators.

I think "last - first" is flawed because the inputs are InputIterators
for which we do not have such notion.

| > Globally, I think that the wording of the requires clause for
| > copy needs work.  But I can't really think of any reasonable way
| > to formulate what common sense tells me should be the
| > restrictions.
|
| Perhaps the requirement should be that the output iterator should not
| produce any side effects in the range [first, last)?

Completely agreed -- and it is the suggestion I made on
news:fr.comp.lang.c++.  It would suffice to make the code duplicate the
content of the list; but it would not suffice to ensure that general
termination, let alone "last - first" assignments.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gcc@integrable-solutions.net (Gabriel Dos Reis)
Date: Tue, 13 Sep 2005 05:30:23 GMT
Raw View
AlbertoBarbati@libero.it (Alberto Ganesh Barbati) writes:

| kanze wrote:
| >
| > Finally, what about something like:
| >
| >     copy( l.begin(), l.end(), back_inserter( l ) ) ;
| >
| > I think that, realistically, this will generally result in an
| > endless loop.  And yet, it requires quite a stretch of the
| > imagination to say that back_inserter( l ) is in the range of
| > [l.begin(),l.end()).
|
| It doesn't result in an endless loop, because l.end() is not
| re-evaluated during the execution of copy.

the "because" part is irrelevant.  See below.

And James' claim that the l.end() is invalidated is bogus.

| The value which is passed as
| the "last" parameter remains a valid iterator which keeps pointing to
| the same element for the whole execution of the algorithm. Therefore the
| statement will effectively just append a entire copy of l at the end of
| l itself.

Consider this:

    p = l.end();
    l.push_back(8);
    q = l.end();
    assert (p == q);

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]