擦除增量习惯用'矢量迭代器不兼容'失败

时间:2014-06-30 17:44:10

标签: c++ visual-studio-2010 iterator stdvector

我已经实现了基于位置的四叉树的SubDivide方法的一部分,如下所示:

//Give elements of mine to children, may or may not accept them.
for(std::size_t i = 0; i < MAX_CHILDREN; ++i) {
    std::vector<T>::iterator b = _elements.begin();
    std::vector<T>::iterator e = _elements.end();
    for(std::vector<T>::iterator _iter = b; _iter != e; ++_iter) {
        if(_children[i]->Add(*_iter)) continue;
    }
}

这种方法的问题在于,当树细分时,父节点如果子节点接受它,则不会从其自己的容器中删除该元素,因此我将其更改为使用擦除增量惯用语:

//Give elements of mine to children, may or may not accept them.
for(std::size_t i = 0; i < MAX_CHILDREN; ++i) {
    std::vector<T>::iterator b = _elements.begin();
    for(std::vector<T>::iterator _iter = b; _iter != _elements.end(); /** DO NOTHING **/) {
        if(_children[i]->Add(*_iter) == false) {
            ++_iter;
            continue;
        }
        _elements.erase(_iter++);
    }
}

但是,在子节点接受元素并且父节点从其容器中删除副本之后,对于for循环的条件检查,vector iterator not compatible失败了。我怀疑通过擦除迭代器的迭代器是无效的(因为它们应该)但是我在其他地方有这个确切的代码(for循环中的条件是不同的,否则涉及迭代器的代码是相同的)并且它不会失败。 / p>

1 个答案:

答案 0 :(得分:2)

关于std::vector erase() iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); (§23.3.6.5[vector.modifiers] / p3),标准可以这样说:

vector
     

效果:在点或之后使迭代器和引用无效   擦除。

因此,擦除增量根本不适用于erase() s。 _iter = _elements.erase(_iter);调用使递增的迭代器无效。请改用#include <vector> #include <iostream> #include <iterator> #include <algorithm> int main(int argc, char* argv[]) { std::vector<int> v; v.push_back(10); v.push_back(20); v.push_back(10); v.push_back(40); v.push_back(10); v.push_back(60); std::vector<int>::iterator b = v.begin(); for(std::vector<int>::iterator _iter = b; _iter != v.end(); /** DO NOTHING **/) { if(*_iter != 10) { ++_iter; continue; } _iter=v.erase(_iter); // v.erase(iter++) causes abort() } std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ")); return 0; }

测试代码 - 这在我的VS 2010上编译并运行良好:

{{1}}