I hit something in GLIBCXX_DEBUG mode the other day and I
want to ask about it.

Do list iterators remain valid after splice and merge operations?

The code is below.  Is this a valid program?  If not, what assumptions
am I violating?

                                  -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;
}

Reply via email to