问题
Porting some code from my game engine from Mac to Windows in C++, and I get this runtime error: "Vector erase outside range". It works on Mac!
void Entity::runDeferreds() {
for (auto it = deferreds.begin(); it != deferreds.end(); /* nothing */ ) {
if (it->Condition()) {
it->Execution();
it = deferreds.erase(it);
} else {
++it;
}
}
}
This iterates thru a list of "deferred" tasks, which are stored in a std::vector<DeferredCall>
called deferreds
. If the DeferredCall
's Condition()
is fulfilled, then its Execution()
is run, and it should be removed from the vector
. However, instead, I get the aforementioned error!
DeferredCall looks like this, not that it's too important:
struct DeferredCall {
std::function<bool()> Condition;
std::function<void()> Execution;
};
Help?!
EDIT:- Alternative Method
I also tried this, again working on Mac:
deferreds.erase(std::remove_if(deferreds.begin(), deferreds.end(),
[](DeferredCall &call) {
if (call.Condition()) {
call.Execution();
return true;
}
return false;
}
), deferreds.end());
However, in this case I get "vector iterators incompatible".
回答1:
Although it doesn't answer where your error comes from, you may try to rework the code as follows:
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());
Also, std::vector::erase is guaranteed to return perfectly valid iterator. Could be vector::end()
though.
Links: std::partition, std::for_each, std::vector::erase
来源:https://stackoverflow.com/questions/28246467/vector-erase-iterator-outside-range