我知道有C ++的擦除删除习惯用法。并且下面的remove方法<algorithm>会将目标元素移到范围的后面。
remove
<algorithm>
但是,以下输出使我感到困惑。
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> vec = {10, 20, 30, 20, 30, 20, 10, 10, 20}; auto pend = remove(vec.begin(), vec.end(), 20); cout << "After removing 20: " << endl; for (const auto& x : vec) { cout << x << " "; } cout << endl; cout << "use pend: " << endl; for (auto p = vec.begin(); p != pend; p++) { cout << " " << *p; } cout << endl; return 0; }
输出为:
After removing 20: 10 30 30 10 10 20 10 10 20 use pend: 10 30 30 10 10
这里有两个问题:
对于“删除20后”,为什么后面有10个与20个混合?10 30 30 10 10 20 10 10 20
对于“ use pend:”,为什么它不能再打印最后两个10?原始向量中有五个10,不应该删除10?
从库中,remove()方法返回迭代器pend
删除模板ForwardIterator(首先使用ForwardIterator,最后使用ForwardIterator,const T&val); 最后一个元素之后未删除的元素的迭代器。first和此迭代器之间的范围包括序列中所有不等于val的元素。
从数组中:
10 20 30 20 30 20 10 10 20
当您删除all时20,您期望得到:
20
10 30 30 10 10
但是std::remove只要移动项目,就可以使其余值未指定:
std::remove
指向范围的新逻辑端和物理端之间的元素的迭代器仍可取消引用,但是元素本身具有未指定的值
这样就得到:
10 30 30 10 10 xx xx xx xx ^ pend
这说明了您的结果。
如果您需要删除项目,请致电vec.erase(pend, vec.end()):
vec.erase(pend, vec.end())
在调用remove之前,通常会先调用容器的擦除方法,该方法将擦除未指定的值并减小容器的物理大小以匹配其新的逻辑大小。