The code below triggers what I think is a bogus assert in GLIBCXX_DEBUG mode. According to http://www.sgi.com/tech/stl/List.html iterators remain valid after a merge operation. I don't have a copy of the standard. Does it say the same? If so, I believe list::merge needs to update the _M_sequence members of the safe iterators merged into the list. I've filed bug 35969. -Dave include <list> #include <iostream> int main(void) { std::list<int> list1; std::list<int> list2; for(int i = 0; i < 10; ++i) { list1.push_back(i); list2.push_back(10-i); } list1.sort(); list2.sort(); std::list<int>::iterator node_of_interest = list2.begin(); // Ok, preserves iterator and updates iterator owner in // GLIBCXX_DEBUG mode list1.splice(list1.begin(), list2, node_of_interest); // Ok, preserves iterator and updates iterator owner in // GLIBCXX_DEBUG mode list2.splice(list2.begin(), list1, node_of_interest); // Oops, does not appear to update iterator owner in GLIBCXX_DEBUG // mode list1.merge(list2, std::less<int>()); // Triggers GLIBCXX_DEBUG error: "attempt to splice an iterator from // a different container." Is node_of_interest still a valid // iterator according to the standard? list2.splice(list2.begin(), list1, node_of_interest); std::cout << "list1:\n"; for(std::list<int>::iterator i = list1.begin(); i != list1.end(); ++i) { std::cout << *i << "\n"; } std::cout << "list2:\n"; for(std::list<int>::iterator i = list2.begin(); i != list2.end(); ++i) { std::cout << *i << "\n"; } return 0; }