Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用迭代器从STL multiset中删除元素_C++_Data Structures_Stl_Multiset - Fatal编程技术网

C++ 使用迭代器从STL multiset中删除元素

C++ 使用迭代器从STL multiset中删除元素,c++,data-structures,stl,multiset,C++,Data Structures,Stl,Multiset,我在一个单独的数据结构中维护多集容器的一组迭代器。过了一会儿,我从这个数据结构中选择了一个迭代器,然后从multiset中删除该迭代器的相关元素。我先用这样的东西: #include <iostream> #include <set> int main () { std::multiset<int> myints; std::cout << "0. size: " << myints.size() << '\n';

我在一个单独的数据结构中维护多集容器的一组迭代器。过了一会儿,我从这个数据结构中选择了一个迭代器,然后从multiset中删除该迭代器的相关元素。我先用这样的东西:

#include <iostream>
#include <set>

int main ()
{
  std::multiset<int> myints;
  std::cout << "0. size: " << myints.size() << '\n';

  for (int i=0; i<10; i++) myints.insert(i);
  std::cout << "1. size: " << myints.size() << '\n';

  myints.insert (5);
  std::cout << "2. size: " << myints.size() << '\n';

  std::multiset<int>::iterator it = myints.find(5);
  myints.erase (it);
  std::cout << "3. size: " << myints.size() << '\n';
  myints.erase (it);
  std::cout << "4. size: " << myints.size() << '\n';
  return 0;
}
erase(it)
使迭代器
it
无效,即在
erase
之后,迭代器无效,对其执行任何操作都会导致未定义的行为。(当它指向的元素被擦除时,您可能希望它“移动到下一个元素”,但它不是这样做的。)

你的第二种方法不能解决这个问题。它可能是偶然工作的,但在擦除它之后,您仍然在重用它



编辑:根据您的描述“我只想从multiset中擦除一个5,并在擦除后保持其有效,以便下次擦除”。您可以通过创建迭代器的副本,增加原始值,然后通过副本擦除来实现这一点:

it = myints.find(5);
// better add a check here to make sure there actually is a 5 ...
std::multiset<int>::iterator newit = it;
it++;
myints.erase(newit);
it=myints.find(5);
//最好在这里添加一个检查,以确保实际上有一个5。。。
std::multiset::iterator newit=it;
it++;
myints.erase(newit);
由于您已经将它递增,它仍然有效,因为它不指向被擦除所杀死的元素


然而,老实说,我无法想象在什么情况下,这可能是有用的,或者说是必需的。

在您的第一种方法中,当您删除迭代器指向的元素时,迭代器将失效,稍后当您尝试再次使用同一迭代器擦除时,您将出现分段错误。
在您的第二种方法中,因为每次执行find after erase时,它都会为您提供正确的迭代器

您可以通过在代码中进行以下更改来修复第一种情况。后增量操作符将返回一个新对象,并将迭代器移动到下一个位置。我还建议在擦除之前做一个结束检查,否则会得到未定义的行为

      std::multiset<int>::iterator it = myints.find(5);
      if(it != myints.end())
      myints.erase (it++);
      std::cout << "3. size: " << myints.size() << '\n';
      if(it != myints.end())
      myints.erase (it++);
      std::cout << "4. size: " << myints.size() << '\n';
std::multiset::iterator it=myints.find(5);
if(it!=myints.end())
myints.erase(it++);

这两种方法都有错误吗?你能更清楚地解释一下你到底想做什么吗?我用multiset容器构建了一个排序列表。因此,我需要删除排序列表中间的一些元素,而不知道它们的键。例如,1 2 3 4的排序列表。过了一会儿,我需要从排序列表中删除一个元素(比如中间的元素),而不知道它的键。因此,我维护一组迭代器,指向单独数据结构中排序列表的每个元素,稍后,我将选择一个迭代器并从排序列表中删除相关元素。是的,但您需要删除哪些元素?删除元素的条件是什么?如果您不知道键,如何删除元素?在任何插入或擦除操作之后,位于外部数据结构中的任何迭代器都可能无效。你不能这样做。有没有办法在擦除(它)后保持它的活动状态(指向具有相同键的下一个元素)?可能没有具有“相同键”的下一个元素(我猜你只是指等效的下一个元素-这是一个多集,而不是多映射)。你到底想做什么?从multiset中删除所有5个?我只想从multiset中删除一个5,并在删除后保持它的有效性,以便下次删除。@ARH对什么有效?您刚刚删除了它所指的元素。@jmucchiello给出了关于我答案的第一条评论,我认为他的意思是“在删除的元素之后直接指向该元素”,尽管我质疑这对于像
多集
这样的排序结构的实用性。
      std::multiset<int>::iterator it = myints.find(5);
      if(it != myints.end())
      myints.erase (it++);
      std::cout << "3. size: " << myints.size() << '\n';
      if(it != myints.end())
      myints.erase (it++);
      std::cout << "4. size: " << myints.size() << '\n';