0

ゲーム エンジンのコードを C++ で Mac から Windows に移植すると、次のランタイム エラーが発生します:「Vector erase outside range」。マックで動く!

void Entity::runDeferreds() {
    for (auto it = deferreds.begin(); it != deferreds.end(); /* nothing */ ) {
        if (it->Condition()) {
            it->Execution();

            it = deferreds.erase(it);
        } else {
            ++it;
        }
    }
}

std::vector<DeferredCall>これは、呼び出された に格納されている「遅延」タスクのリストを反復処理しdeferredsます。DeferredCallCondition()満たされている場合は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());

ただし、この場合、「ベクトル反復子に互換性がありません」と表示されます。

4

1 に答える 1

5

エラーの原因はわかりませんが、次のようにコードを作り直すことができます。

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::partitionstd::for_eachstd::vector::erase

于 2015-01-31T00:06:43.660 に答える