Re: Best way to append std::list to itself
On Jan 6, 6:28 pm, Jorgen Grahn <grahn+n...@snipabacken.se> wrote:
On Thu, 2011-01-06, Marcel M ller wrote:
Yes, and according to the guarantees of std::list it will
always point to one past the last element in the container.
That's an interesting assertion. I don't think that the
standard is clear here: does the end iterator point to one past
the last element, always, or does it point to one past the last
element when it was called. I.e.:
std::list<char> l;
l.push_back('a');
l.push_back('b');
l.push_back('c');
std::list<char>::iterator i = l.end();
// i points to one past the element 'c'
l.push_back('d');
// i points to one past the element 'c'?
// or one past the new last element.
I don't think that the standard is really clear here. (I don't
think it's an issue for other containers---in vector, for
example, insertion invalidates any iterators behind the point of
insertion, and thus, any end iterator.)
Regardless of the insertions at the end.
The range is not extended by anything, and there
is no infinite loop.
Wrong!
Simply test it.
Did *you* test it? How?
#include <list>
#include <iostream>
int main()
{
std::list<int> foo;
foo.push_back(1);
foo.push_back(2);
foo.push_back(3);
foo.insert(foo.end(), foo.begin(), foo.end());
for(std::list<int>::const_iterator i = foo.begin(); i!=foo.end(); ++i) {
std::cout << *i << '\n';
}
return 0;
}
In what way am I wrong? I see no infinite loop. On my system
this prints 1 2 3 1 2 3 and that's also what I'd expect.
In this particular case, I wouldn't expect anything. The
standard states that for a.insert(p, i, j) (regardless of the
container type, see table 67), there is a precondition that
i and j are not iterators into a. You've violated
a precondition, so the results are undefined behavior. In
a good implementation, I would expect the equivalent of an
assertion failure. (None that I have access to do detect this
error, however. Even though they can make the connection
between iterator and the associated container; e.g. they
complain if the first iterator into the assert isn't an iterator
into foo.)
The question still remains concerning my first example. If
I then do:
for (std::list<char>::iterator j = l.begin(); j != i; ++ j)
std::cout << *j;
, how many characters do I output. Both of the compilers
I have access to output "abcd". Even though with the code using
insert, one goes into an infinite loop (until running out of
memory), and the other generates "123123".
--
James Kanze