Are std::list iterators broken in VC++2008?
From my understanding of STL, list iterators are supposed to remain valid after a splice operation, however I seem to be getting a problem when I use an iterator to splice one object from list A to list B. The iterator seems to have been invalidated by the STL implementation. If I then try to use the same iterator to splice the object back from list B to list A, "bad things" happen (assertion fail on a debug build, worse on a release build). Here is a simple test case:
#include <list>
#include <assert.h>
typedef std::list<int> IntList;
extern "C" int main(int argc, char *argv[])
{
IntList list1, list2;
IntList::iterator iter = list1.insert(list1.end(), 42);
list2.splice(list2.end(), list1, iter);
list1.splice(list1.end(), list2, iter);
assert(list1.size() == 1);
assert(list2.empty());
assert(*(list1.begin()) == 42);
return 0;
}
This code builds and appears to run fine using GCC, but not with Visual Studio 2008 (the second splice operation fails an internal assertion). Am I missing something fundamental here or is this a problem with VC++?
Peter
Re: Are std::list iterators broken in VC++2008?
I am not sure, but I think the result of the second splice operation
is undefined. According to the standard, the splice operation:
Quote:
Invalidates only the iterators and references to the spliced element
So, I read that to mean that the first splice operation would invalidate
the iterator (iter) , which you use in the second splice operation.
I could be wrong ... I am not a language expert on these types
of matters.
Re: Are std::list iterators broken in VC++2008?
I suspect you are correct, at least from what I can tell tracing through VC++'s STL list source. The problem is relatively easily fixed/worked around by reassigning the iterator to list2.end() and decrementing it after the first splice, but one line of code is usually preferable to three :)