Expression: vector iterators incompatible 错误通常是在使用 C++ 的标准库容器时发生的,特别是 std::vector,当迭代器失效或者不兼容时。对C++不太熟,记录一个比较有意思的bug。

学弟的一段打怪兽游戏代码

void spawnTreasure() {
        float x = static_cast<float>(std::rand() % (window.getSize().x - 20));
        float y = static_cast<float>(std::rand() % (window.getSize().y - 20));
        treasures.push_back(Treasure(treasureTexture, x, y));
    } for (auto it = treasures.begin(); it != treasures.end(); /* 空 */) {
                if (dog->getBounds().intersects(it->getBounds())) {
                    if (soundEnabled) {
                        dog->bark();
                    }
                    score++;
                    updateScoreText();
                    it = treasures.erase(it); 
                    spawnTreasure();
                }
                else {
                    ++it;
                }
             }

主要的问题出在spawnTreasure函数调用的位置上。当你在删除一个元素并立即在相同的循环中调用 spawnTreasure 时,可能会导致迭代器失效。因为 spawnTreasure 添加了一个新元素到 treasures 中,这可能会引起容器重新分配内存,从而使得所有现有的迭代器失效。

一种常见的解决方案是将spawnTreasure的调用推迟到循环外,以避免在迭代器失效的情况下操作容器。使用一个布尔变量来标记是否需要生成新的宝藏,并在循环结束后生成新的宝藏。

void spawnTreasure() {
    float x = static_cast<float>(std::rand() % (window.getSize().x - 20));
    float y = static_cast<float>(std::rand() % (window.getSize().y - 20));
    treasures.push_back(Treasure(treasureTexture, x, y));
}

void checkTreasureCollision() {
    bool shouldSpawnTreasure = false;

    for (auto it = treasures.begin(); it != treasures.end(); /* 空 */) {
        if (dog->getBounds().intersects(it->getBounds())) {
            if (soundEnabled) {
                dog->bark();
            }
            score++;
            updateScoreText();
            it = treasures.erase(it); 
            shouldSpawnTreasure = true;
        } else {
            ++it;
        }
    }

    if (shouldSpawnTreasure) {
        spawnTreasure();
    }
}

文章作者: 易百分
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 易百分 !
  目录