Cha*_*l72 14 c++ iterator stl vector
之前有一些关于这个问题的问题; 我的理解是,调用std::vector::erase只会使处于擦除元素之后的位置的迭代器无效.但是,在擦除元素之后,该位置的迭代器是否仍然有效(当然,前提是它end()在擦除后没有指向)?
我对如何实现向量的理解似乎表明迭代器肯定是可用的,但我不完全确定它是否会导致未定义的行为.
作为我正在谈论的一个例子,下面的代码从向量中删除所有奇数整数.此代码是否会导致未定义的行为?
typedef std::vector<int> vectype;
vectype vec;
for (int i = 0; i < 100; ++i) vec.push_back(i);
vectype::iterator it = vec.begin();
while (it != vec.end()) {
if (*it % 2 == 1) vec.erase(it);
else ++it;
}
Run Code Online (Sandbox Code Playgroud)
代码在我的机器上正常运行,但这并不能说服它是有效的.
Jam*_*lis 36
擦除元素后,该位置的迭代器仍然有效
没有; 传递给它的迭代器之后或之后的所有迭代器erase都是无效的.
但是,erase返回一个新的迭代器,它指向被删除的元素之后的元素(如果没有这样的元素,则指向结尾).您可以使用此迭代器继续迭代.
请注意,这种删除奇数元素的特殊方法效率非常低:每次删除元素时,其后的所有元素都必须在向量中向左移动一个位置(这是O(n 2)).您可以使用erase-remove惯用法(O(n))更有效地完成此任务.您可以创建is_odd谓词:
bool is_odd(int x) { return (x % 2) == 1; }
Run Code Online (Sandbox Code Playgroud)
然后这可以传递给remove_if:
vec.erase(std::remove_if(vec.begin(), vec.end(), is_odd), vec.end());
Run Code Online (Sandbox Code Playgroud)