矢量擦除迭代器超出范围[关闭]
Posted
技术标签:
【中文标题】矢量擦除迭代器超出范围[关闭]【英文标题】:Vector erase iterator outside range [closed] 【发布时间】:2015-01-30 23:45:11 【问题描述】:使用 C++ 将我的游戏引擎中的一些代码从 Mac 移植到 Windows,我收到此运行时错误:“矢量擦除超出范围”。它适用于 Mac!
void Entity::runDeferreds()
for (auto it = deferreds.begin(); it != deferreds.end(); /* nothing */ )
if (it->Condition())
it->Execution();
it = deferreds.erase(it);
else
++it;
这会遍历“延迟”任务列表,这些任务存储在名为 deferreds
的 std::vector<DeferredCall>
中。如果DeferredCall
的Condition()
被满足,那么它的Execution()
被运行,它应该从vector
中被移除。但是,相反,我得到了上述错误!
DeferredCall 看起来是这样的,并不是说它太重要了:
struct DeferredCall
std::function<bool()> Condition;
std::function<void()> Execution;
;
帮忙?!
编辑:- 替代方法
我也试过这个,再次在 Mac 上工作:
deferreds.erase(std::remove_if(deferreds.begin(), deferreds.end(),
[](DeferredCall &call)
if (call.Condition())
call.Execution();
return true;
return false;
), deferreds.end());
但是,在这种情况下,我得到“向量迭代器不兼容”。
【问题讨论】:
你不应该在擦除(它)之后跳出循环吗?否则,您将再次迭代相同的已擦除迭代器。 回调是否可以(甚至间接)访问deferreds
。可以在回调中修改吗?
@DanSimmons: std::vector::erase
在此代码分配给it
的已移除元素之后返回一个迭代器。这段代码看起来正确地实现了一个常见的习惯用法。
这两个看起来都不错。这是您的实际代码还是只是一个示例?我问的原因是,大多数情况下,当您看到“迭代器不兼容”消息时,这是因为向量是按值返回的,而不是从 get 函数中引用。
***.com/help/mcve
【参考方案1】:
虽然它没有回答你的错误来自哪里,但你可以尝试重新编写代码,如下所示:
const auto pred = [](Deferred& d) return !d.Condition(); ;
auto itMatch = std::partition( defs.begin(), defs.end(), pred);
const auto action = [](Deferred& d) d.Execution(); ;
std::for_each(itMatch, defs.end(), action);
defs.erase(itMatch, defs.end());
另外,std::vector::erase 保证返回完全有效的迭代器。不过可能是vector::end()
。
链接:std::partition、std::for_each、std::vector::erase
【讨论】:
好主意。这避免了在传递给std::remove_if
的谓词中的对象上调用非常量函数的未定义行为@以上是关于矢量擦除迭代器超出范围[关闭]的主要内容,如果未能解决你的问题,请参考以下文章