c++ - 删除一个外部迭代器

标签 c++ iterator erase

我试验了以下代码

list<int> a ={1,2};
list<int> b ={3,4};
a.erase(b.begin());
for (auto x:b) cout << x << endl;

奇怪的是,程序运行良好,没有出现任何错误。它打印出来的是 4。我想知道为什么当对象已经隐含在迭代器中时 erase 是一个成员函数。

最佳答案

a.erase(b.begin());

这会调用未定义的行为,因为您将从一个容器获取的迭代器传递给另一容器的函数。 ab 是两个不同的容器,它们不一样。

未定义的行为意味着任何事情都可能发生:它可能按预期运行,也可能不运行。语言规范和编译器都不能保证它能够正常工作。恰如其分地说“未定义的行为”。

你应该做的是:

auto value = *(b.begin()); //value is int
auto it = std::find(a.begin(), a.end(), value); //returns iterator 
if ( it != a.end())
   a.erase(it); //well-defined, as the iterator belongs to the same container!

或者,如果您想删除所有等于 value 的元素,那么您可以简单地执行以下操作:

a.remove(value); //std::list has remove member function

但是,如果您使用大多数情况下应该使用的 std::vector 。它是 C++ 中的默认容器类型,只有当您有充分理由这样做时才应使用 std::list:

std::vector<int> a ={1,2};
std::vector<int> b ={3,4};

//if you want to remove one element:
auto value = *(b.begin()); //value is int
auto it = std::find(a.begin(), a.end(), value); //returns iterator 
if ( it != a.end())
   a.erase(it); //well-defined, as the iterator belongs to the same container!

如果你想删除所有等于value的元素,那么你可以应用流行的Erase-Remove Idiom:

a.erase(std::remove(a.begin(), a.end(), value), a.end()); 

请注意,std::vector 没有remove() 成员函数,这就是您应用此习惯用法的原因。您可以阅读 my answer here,其中对此进行了更详细的讨论。

关于c++ - 删除一个外部迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9242194/

相关文章:

c++ - remove_if and then erase 在 vector 上是否有效?

c++ - C++编程基础问题

c++ - 为什么非常量引用不能绑定(bind)到临时对象?

c++ - 什么是 'required from here' 错误

c++ - 在类中创建类的实例

c++11 - 如何允许派生类通过虚拟方法返回类型上的任何迭代器?

python 迭代器、生成器以及介于两者之间的

java - 类和迭代器接口(interface)之间的关系

c++ - Erase() 对 C++ 不起作用

c++ - vector 保存类对象,类对象每个对象包含 3 个字符串。如何找到特定字符串,然后删除整个元素?