gpt4 book ai didi

c++ - 比较来自一个 vector 的迭代器时,什么会引发 'iterators are incompatible'?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:03:34 25 4
gpt4 key购买 nike

我正在研究 UI。 UI 组件的基类是 UILayout ,整个 UI 是一棵 UILayout 对象树,根是代表整个屏幕的 UILayout。为了包含这个层次结构,任何给定的 UILayout 都有一个 boost::shared_ptr<UILayout> 的 vector mChildren .

UIManager 对象负责更新 UILayout 的整个层次结构。对 Update 的每次调用都会遍历 vector mChildren,递归地对每个 child 调用 Update。

因为更改 vector 的形状会使那些迭代器失效,所以从 mChildren 添加和删除条目仅限于 ResizeChildren 方法。当组件需要添加或删除时,它们被添加到两个 vector 之一,mChildrenPendingAddition 和 mChildrenPendingRemoval。在 Update 循环之前,调用 ResizeChildren,并相应地更新 mChildren。 (如果这是处理这个特定问题的愚蠢方法,请阻止我。)

当我尝试从 mChildren 中删除所有也包含在 mChildrenPendingRemoval 中的条目时,我遇到了异常。来自 UILayout::ResizeChildren():

mChildren.erase(remove_if(mChildren.begin(), mChildren.end(),
IntersectsWithChildrenPendingRemoval(this)), mChildren.end());

IntersectsWithChildrenPendingRemoval 的比较函数调用 this->ChildrenPendingRemovalContains(HUILayout ly),它执行以下操作:

return (find(mChildrenPendingRemoval.begin(), mChildrenPendingRemoval.end(),
ly) != mChildrenPendingRemoval.end());

该行有时 无法通过调试断言vector iterators incompatible。关于这个错误有很多现有的问题,但它似乎通常表明正在比较来自不同容器的两个迭代器。但在这里,显然不是这样,对吧?还有什么可能导致此问题?

相关源码:

这是我为多线程应用程序开发的插件。事实上,问题以非常罕见和随机的间隔出现,这让我相信这与插件在单独的线程中运行这一事实有关,但所有这些方法都是从一个函数调用的,完全是在一个单一的线程,并且 mChildren 不会在任何其他线程中访问或修改。

最佳答案

Please stop me if this is an asinine way of handling this particular problem

您为什么不制作该系列的拷贝,并立即将其交换:

std::list<X> copy(mChildren);

copy.insert(...);
copy.remove(...);
copy.insert(...);

// at once:
std::swap(copy, mChildren);

进一步的思考:

  • 将迭代器在任何时间段内保存在可变容器中通常不是很方便

  • 因为这是一个智能指针的容器...如果您需要保留 ',为什么不自己传递智能指针本身指向元素的指针? (当然,这不会启用迭代,但 IMO 无论如何都不是一个非常健康的愿望)

关于c++ - 比较来自一个 vector 的迭代器时,什么会引发 'iterators are incompatible'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8318338/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com