在处理《代码的降临》时,我遇到了一个问题,我试图向后迭代“Scratchcard”对象向量,并且迭代器不会随着 for 循环的进行而更新,从而创建无限循环。
所讨论的代码块应该迭代 Scratchcard 对象的一个向量,并将其与 Scratchcard 对象的第二个向量进行比较。与第二个向量的比较通过反向迭代器 for 循环进行,使用“it”向后遍历第二个向量。然后,第二个 for 循环比较两个刮刮卡对象的 ID,如果它们不相同,则检查 ID 是否在特定范围内。如果是,则在“it”处放置该对象的副本,然后继续向后遍历向量,直到找到具有相同 ID 的刮刮卡对象。
int totalScratchcards = 0;
for (int i = 0; i < cards.size(); i++) {
totalScratchcards += 1 + cards.at(i).getWinningNumbers();
if (cards.at(i).getWinningNumbers() > 0) {
int currentCardID = cards.at(i).getID();
int numOfWins = cards.at(i).getWinningNumbers();
// Loop that is broken - commenting out the body of the loop allows the loop to function
for (std::vector<Scratchcard>::reverse_iterator it = cards.rbegin(); it != cards.rend(); ++it) {
if ((*it).getID() == cards.at(i).getID())
break;
if (inRange((*it).getID(), currentCardID, currentCardID + numOfWins))
it = std::vector<Scratchcard>::reverse_iterator(cards.emplace(it.base(), *it));
}
}
}
当我注释掉第二个 for 循环内的代码时,它将成功循环两个向量。但是,当我没有注释掉代码时,它会进入无限循环,其中“它”永远不会从初始值发生变化,尽管任何 if 语句都不会返回 true。实际上,它永远在两个 if 语句之间跳动,因为“it”永远不会改变,并且两个 if 语句的计算结果都不为 true。我最好的猜测是,在 if 条件中使用指针取消引用会破坏循环,但我不明白为什么或如何让它工作。
在迭代它的循环中修改
cards
(在本例中,通过调用 emplace
can 使现有迭代器无效。寻求一种在迭代向量或其他集合时不修改向量或其他集合的解决方案。
来自 emplace
上的 cppreference
page:
如果操作后新的 size() 大于旧的capacity(),则会发生重新分配,在这种情况下,所有迭代器(包括 end() 迭代器)和对元素的所有引用都将无效。否则,只有插入点之前的迭代器和引用仍然有效。