可能重复:
STL删除无法按预期工作?
对不起,我是C++ 11和迭代器的新手.这应该删除数组中的所有数字3,但它不会删除最后一个.为什么?
#include <algorithm>
#include <array>
#include <iostream>
int main() {
std::array<int, 8> a{{9, 3, 4, 5, 33, 5, 6, 3}};
int N(3);
std::remove(a.begin(), a.end(), N);
for (int i : a) {
std::cout << i << '\n';
}
}
Run Code Online (Sandbox Code Playgroud)
我得到输出:
{ 9, 4, 5, 33, 5, 6, 6, 3 }
^
|
// the last 3 is still there
Run Code Online (Sandbox Code Playgroud)
std::remove在迭代器上运行; 因此,它无法从容器中实际擦除元素.这就是为什么它通常与erase以下一起使用:
a.erase(std::remove(a.begin(), a.end(), N), a.end());
Run Code Online (Sandbox Code Playgroud)
正如其他人所说,这不适用array.
算法不了解底层容器.它们只是根据给定的迭代器进行迭代,并独立于容纳它们的容器访问元素.这就是为什么有一种称为擦除删除的习惯用法,它采用以下模式:
container.erase(std::remove(it1, it2, value), std::end(container));
Run Code Online (Sandbox Code Playgroud)
std::remove将保留的元素移动到前面(感谢K-ballo)并将迭代器返回到未移动元素的开头.然后,erase擦除从那一点到结束的所有内容.
由于std::array封装了固定大小的数组,我将使您的示例适应std::vector:
std::vector<int> v{9, 3, 4, 5, 33, 5, 6, 3};
v.erase(std::remove(std::begin(v), std::end(v), 3), std::end(v));
Run Code Online (Sandbox Code Playgroud)
唯一的其他东西要注意的是较为普遍的形式.begin()和.end(),这在内置阵列工作也是如此.这包含在C++ 11中.