【发布时间】: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 函数中引用。