当比较来自单个向量的迭代器时,会引起什么'iterators are incompatible'?
What would provoke 'iterators are incompatible' when comparing iterators from one single vector?
我正在做一个UI。UI组件的基类是UILayout
,整个UI是一个UILayout对象树,根是代表整个屏幕的UILayout。为了包含这个层次结构,任何给定的ui布局都有一个向量mChildren boost::shared_ptr<UILayout>
。
UIManager对象负责更新整个ui布局的层次结构。每次调用Update都会迭代vector mChildren,递归地对每个子类调用Update。
因为改变vector的形状会使这些迭代器失效,所以从mChildren中添加和删除条目仅限于ResizeChildren方法。当需要添加或删除组件时,它们被添加到两个向量之一,mChildrenPendingAddition和mChildrenPendingRemoval。在Update循环之前,ResizeChildren被调用,并相应地更新mChildren。(如果这是一个愚蠢的处理这个问题的方法,请阻止我。)
当我试图从mChildren中删除也包含在mChildrenPendingRemoval中的所有条目时,我得到了一个异常。从UILayout: ResizeChildren ():
mChildren.erase(remove_if(mChildren.begin(), mChildren.end(),
IntersectsWithChildrenPendingRemoval(this)), mChildren.end());
IntersectsWithChildrenPendingRemoval的比较函数调用这个->ChildrenPendingRemovalContains(HUILayout ly),它做以下事情:
return (find(mChildrenPendingRemoval.begin(), mChildrenPendingRemoval.end(),
ly) != mChildrenPendingRemoval.end());
那行有时调试断言vector迭代器不兼容失败。关于这个错误存在很多问题,但它似乎通常表明正在比较来自不同容器的两个迭代器。但在这里,显然不是这样的,对吧?还有什么可能导致这个问题?
相关源代码:
- 类和谓词定义
- 违规方法的实施
这是一个插件,我正在开发一个多线程应用程序。这个问题以非常罕见和随机的间隔出现的事实使我相信它与插件在单独的线程中运行的事实有关,但是所有这些方法都是从单个函数调用的,在单个线程中,并且mChildren不能在任何其他线程中访问或修改。
如果这是一个愚蠢的处理这个问题的方法,请阻止我
你为什么不做一个集合的副本,并立即交换它:
std::list<X> copy(mChildren);
copy.insert(...);
copy.remove(...);
copy.insert(...);
// at once:
std::swap(copy, mChildren);
进一步的想法:
在任意一段时间内将迭代器保存在可变容器中通常不是很方便
因为这是一个智能指针的容器…如果需要保留指向元素的指针,为什么不传递智能指针本身呢?(当然,这不会实现迭代,但在我看来,这不是一个非常健康的愿望)
使用索引代替迭代器。迭代器被高估了。它们只不过是一般的指针。在矢量中管理项的最佳方法一直是使用索引。如果你想使用迭代器,试试std::list,在这种情况下,即使你向列表中添加或删除元素,迭代器也不会失效。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- ifstream什么都没读
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- std::d eque : "insertion and deletion of elements may invalidate iterators"是什么意思?
- 当比较来自单个向量的迭代器时,会引起什么'iterators are incompatible'?