c ++迭代器比较断言失败

时间:2016-04-08 12:15:34

标签: c++ arrays list iterator

我有一个列表list<x> bar和一个迭代器数组list<x>::iterator foo[100]使用bar.end()初始化了所有元素。

我希望将foo中的指针存储到bar中的某些元素,同时我将擦除,插入和推送元素转换为bar。对于元素插入,我必须检查foo中的位置是否为空:

if (foo[my_number] != bar.end())
  //do something 1
else
  //do something 2

仅在foo[my_number]已指向bar元素的情况下才会收到错误。 if为真我收到此错误(如果错误,没问题):

Debug Assertion Failed!

Program: C:\Windows\system32\MSVCP120D.dll
File: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\list
Line: 289

Expression: list iterators incompatible

我看了http://techlovejump.com/android-multicolumn-listview/,插入后bar.end()与以前不一样。但是,如果我推回元素并比较bar.endfoo[k] = end,我的代码就不会失败。但无法将bar.endfoo[k] = bar.begin() + p进行比较(此bar元素存在)。

我错过了什么?我怎样才能克服这个问题?插入元素后,我应该重新实现foo吗?

2 个答案:

答案 0 :(得分:2)

std::list中的

insertpush_back操作不会使迭代器或引用无效。 erase使擦除元素的迭代器(和引用)无效。问题是由于你使用迭代器擦除元素,擦除之后(或之前),你应该在数组中更新这个元素迭代器 - 最好是end迭代器。

问题是你应该先找到它,所以在擦除之前你可能需要搜索它。如何计划保持数组和列表的同步?

以下是您可以做什么和不应该做的一些示例:

  std::list<int> lst;
  std::vector<std::list<int>::iterator> arr;

  // Init arr with end() iterator
  arr.push_back(lst.end());

  // Add new list element
  lst.push_back(0);

  // Remember where it is in arr
  arr[0] = lst.begin();

  // Compare it.
  if ( arr[0] == lst.begin())
  {
    std::cout << "this is OK!\n";
  }

  lst.push_back(0);

  if (arr[0] == lst.begin())
  {
    std::cout << "this is still OK!\n";
  }

  lst.erase(lst.begin());
  //arr[0] = lst.end(); - without this, "list iterators incompatible" is issued by VS below
  if (arr[0] == lst.begin())
  {
    // list iterators incompatible
    std::cout << "This is WRONG!\n";
  }

答案 1 :(得分:2)

擦除std::list中的元素会使指向它的迭代器无效(请参阅here)。因此,如果您从bar进行擦除,请务必从foo中删除相应的迭代器。所有其他std::list操作都应该保持现有的迭代器有效。

您找到的链接指向有关std::vector的问题,该问题在迭代器失效方面表现不同。