C++ 特性之vector详解 + 联合opencv使用
在C++中,遍历vector并删除元素需要小心处理迭代器失效的问题。通常推荐的方法是使用迭代器进行遍历,并在需要删除元素时使用erase函数。这里给出一个示例代码,演示如何安全地遍历vector并删除特定条件的元素:
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};// 遍历vector,并删除偶数for (auto it = vec.begin(); it != vec.end(); /* 注意:不在此处增加it */ ) {if (*it % 2 == 0) {it = vec.erase(it); // erase会返回下一个有效的迭代器} else {++it; // 只有在不删除元素时才移动迭代器}}// 输出剩余的元素for (auto num : vec) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
在C++中,std::vector 是一种非常灵活的容器,允许你存储任意类型的动态数组。然而,std::vector 本身并不直接提供一个名为 “删除元素” 的成员函数。不过,你可以使用几种不同的方法来从 vector 中移除元素。
- 使用 erase 和 remove(或 remove_if)
这是移除元素最常见的方法,它结合了算法库中的 remove(或 remove_if,如果你基于条件移除)和 vector 的 erase 成员函数。remove(或 remove_if)将需要删除的元素移动到容器的末尾,并返回一个迭代器指向新逻辑末尾(即最后一个未被移除的元素之后的位置),然后你可以使用 erase 来实际删除这些元素。
#include <vector>
#include <algorithm> // 包含 remove 和 remove_if std::vector<int> vec = {1, 2, 3, 4, 5, 2, 2, 7}; // 移除所有值为 2 的元素
vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end()); // 或者,使用 lambda 表达式和 remove_if 移除所有偶数
vec.erase(std::remove_if(vec.begin(), vec.end(), [](int i){ return i % 2 == 0; }), vec.end());
- 直接访问并删除
如果你知道要删除的元素的确切位置,可以直接使用 erase 来删除它。但请注意,这只会删除一个元素,并且你需要确保索引是有效的。
std::vector<int> vec = {1, 2, 3, 4, 5}; // 假设我们要删除索引为 2 的元素(即值为 3 的元素)
vec.erase(vec.begin() + 2);
- 清除整个容器
如果你想删除容器中的所有元素,可以简单地使用 clear 成员函数。
std::vector<int> vec = {1, 2, 3, 4, 5};
vec.clear(); // 现在 vec 是空的
注意事项
使用 erase 时,由于它会改变容器的大小并可能使迭代器失效,因此务必小心处理迭代器。在 erase 操作后,所有指向被删除元素(包括被删除元素之后的所有元素)的迭代器、指针和引用都将变得无效。
remove 和 remove_if 函数并不实际删除元素,它们只是将不需要的元素移动到容器的末尾,并返回一个迭代器指向新逻辑末尾的位置。你需要配合 erase 来实际删除这些元素。
当使用基于范围的 for 循环时,由于迭代器可能会失效,因此不适合直接在循环体中使用 erase(除非你能确保不会删除当前迭代器指向的元素)。在这种情况下,你可以考虑使用上述的 erase-remove 惯用法或使用索引进行迭代。