我试验了以下代码
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());
这会调用未定义的行为,因为您将从一个容器获取的迭代器传递给另一容器的函数。 a
和 b
是两个不同的容器,它们不一样。
未定义的行为意味着任何事情都可能发生:它可能按预期运行,也可能不运行。语言规范和编译器都不能保证它能够正常工作。恰如其分地说“未定义的行为”。
你应该做的是:
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/