我有一个在Linux机器上编写的程序。它使用a std::vector<std::string>
,我用for循环遍历它,就像这样
std::vector<std::string> words;
words.push_back("A");
words.push_back("B");
words.push_back("C");
// loop
for (auto it = words.end(); it >= words.begin(); it--)
{
std::string word = *it; // invalid deref?
// do things with word
if (word == "B")
{
words.erase(it);
}
std::cout << word << std::endl;
}
int i = 0;
for (std::string word : words)
{
std::cout << i++ << word << std::endl;
}
使用g ++作为编译器,可以按预期运行,打印C,B和A。但是,当我使用VisualStudio运行它时,会收到无效的解除引用异常。
我向后遍历向量,因为我想从中删除项目,如果向前循环则与迭代器混淆。
我有一个使用整数并使用获取项目的解决方法std::vector<std::string>.at(int)
,但是我很好奇为什么这适用于我的linux机器而不是Windows?
正如您正确评论的那样,存在无效的取消引用。
std::string word = *it;
将std::string word = *words.end()
在第一次迭代中导致不确定的行为。因此,在一个系统上工作并在另一个系统上引发异常是完全有效的。
反向迭代向量的正确方法是
for(auto it = words.rbegin(); it != words.rend(); it++) {...}
但是,对于从矢量中删除元素,“擦除删除惯用语”可能更有用:
words.erase(std::remove(words.begin(), words.end(), "B"), words.end());
或者,如果您的情况更复杂,请使用lambda:
words.erase(std::remove_if(
words.begin(),
words.end(), [](const std::string &name){return name == "B";}
), names.end());
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句