我想打印出multiset中的每个重复项,但不知何故迭代器对我来说很奇怪。如何修复此代码?这段代码导致了一个永远的循环,让我感到惊讶。
#include <set>
#include <iostream>
#include <sstream>
static void print_duplicate(const std::multiset<int>& mset)
{
std::stringstream error_msg;
for (auto it = mset.begin(); it != mset.end(); ++it)
{
unsigned count = mset.count(*it);
if (count < 2)
continue;
error_msg << "Duplicated numbers found:\n";
for (unsigned i = 0; i < count; ++it, ++i)
error_msg << "\tNum:" << *it << "\n";
}
std::cout << error_msg.str();
}
int main()
{
std::multiset<int> mset;
// fill it
mset.insert(1);
mset.insert(1);
mset.insert(1);
print_duplicate(mset);
}
修改 我在周期结束时添加了一个< - p>
for (unsigned i = 0; i < count; ++it, ++i)
error_msg << "\tNum:" << *it << "\n";
--it; // this line fix it
}
答案 0 :(得分:3)
在外部循环中,您可以多次增加it
。因此,条件it != mset.end()
可能永远不会成立,因为已经跳过了结尾。增加一个过去的迭代器是未定义的行为,这意味着它也可能无声地失败。
一种可能的解决方案可能是检查内部it != mset.end()
循环中的for
:
for (unsigned i = 0; (i < count) && (it != mset.end()); ++it, ++i)
error_msg << "\tNum:" << *it << "\n";
答案 1 :(得分:3)
for (unsigned i = 0; i < count; ++it, ++i)
当此循环结束时,it
将等于mset.end()
,并且由于您仍然拥有主循环中的其他++it
,因此您将获得不同的内容mset.end()
因此程序永远不会结束。
答案 2 :(得分:2)
问题似乎是你在没有检测到的情况下滑过终点。在您创建的mset
中,只有1
个。这意味着count
将为3,嵌套for
(i
上的那个)将执行3次;完成后,it
将等于mset.end()
。然后控制到达外部for
的末尾,it
增加,变得非法,更重要的是,与mset.end()
不同。这意味着外部循环永远不会终止。
答案 3 :(得分:1)
快速修复:在内循环后添加一行:it - ;
在Angew的回答中解释了原因。
答案 4 :(得分:0)
将for循环更改为:
for(std::container::iterator it=mset.begin(), it_next=it; it!=mset.end(); it=it_next) {
++it_next;
...
}
基本上,您正在跳过循环结束,因为您正在针对迭代器检查变量。仅增加辅助迭代器可以防止这种情况发生。