使用迭代器遍历 for 循环时插入和删除多集元素

Insertion and Deletion of Multiset Elements while Traversing through for loop using iterators

提问人:Naruto Uzumaki 提问时间:12/21/2022 最后编辑:wohlstadNaruto Uzumaki 更新时间:12/21/2022 访问量:43

问:

在这里,我正在执行操作和操作,同时遍历 .我写的代码是:eraseinsertmultisetmultiset

#include <bits/stdc++.h>

using namespace std;

int main(){
    multiset<int> ms;
    ms.insert(6);
    ms.insert(7);
    ms.insert(8);
    ms.insert(9);
    ms.insert(10);
    for(auto it = ms.begin();it != ms.end();it++){
        cout << *it << endl;
        ms.erase(it);
        if(*it == 6){
            ms.insert(4);
        }
    }
}

上述代码的输出为: 6 7 4 8 9 10

我无法理解输出以及 4 如何作为输出的一部分进行打印!!

有谁知道输出的解释???

我在使用迭代器遍历 for 循环时尝试了不同的插入和删除操作。总是在某个时候卡住,无法理解输出!!

C++ 迭代器 C++-标准库 多集

评论

0赞 Michael Foukarakis 12/22/2022
的预期用法更类似于。不过,我主要是猜测。erase(iterator)

答:

2赞 wohlstad 12/21/2022 #1

正如您在 multiset::erase 文档中看到的:

对擦除元素的引用和迭代器无效

因此,在这一行之后:

ms.erase(it);

任何去引用的尝试(就像你在下一行中所做的那样)都是UB未定义的行为)。
这意味着任何事情都可能发生。
it*it

一些旁注:

  1. 为什么我不应该 #include < bits/stdc++.h>?
  2. 为什么“using namespace std;”被认为是不好的做法?

评论

0赞 Naruto Uzumaki 12/21/2022
好的,那么不要在 if 语句中再次取消引用迭代器,如果将 *it 的值存储在 int x 中,然后使用这个 x 应该不会给我们带来问题。但即使在这种情况下,输出也保持不变。
0赞 wohlstad 12/21/2022
您可以在调用之前存储 in 的值。*itint xerase
0赞 Naruto Uzumaki 12/21/2022
在这种情况下,输出再次为 6 7 4 8 9 10,您能否解释一下我们如何迭代该集合以及为什么我们在输出中得到 4?根据我的猜测,答案应该是 6 7 8 9 10。
0赞 wohlstad 12/21/2022
你不能那样做。即使在循环中使用实际上也是在取消引用 .删除元素的一种方法是保留另一个带有要擦除的键的元素。然后遍历这个并执行实际的 .it++itvectorvectorerase
0赞 wohlstad 12/21/2022
你能解释一下你想用这段代码做什么吗?