我遇到了问题,我试图删除字符串列表中的元素,但它不适用于最后一个位置。我还想通过算术运算显示迭代器的位置。
列出l = {" a"," b"," c"," d"};
for(std::list<string>::iterator it = l.begin(); it != l.end(); it++)
cout << " &l["<< it - l.begin() <<"]: " << &*it << " l["<< it - l.begin() <<"]: " << *it << endl;
cout << endl;
for(std::list<string>::iterator itt = l.begin(); itt != l.end(); itt++){
if(*itt == "d") itt = l.erase(itt);
cout << " &l["<< itt - l.begin() <<"]: " << &*itt << " l["<< itt - l.begin() <<"]: " << *itt << endl;
}
感谢您的帮助。
答案 0 :(得分:2)
它“不起作用”,因为在删除最后一个元素时,该行将导致itt
成为end()
迭代器:
if(*itt == "d") itt = l.erase(itt);
然后for
循环在循环条件检查之前执行itt++
,并且递增end()
迭代器是未定义的行为。
您需要像这样修改循环:
for (std::list<string>::iterator itt = l.begin(); itt != l.end(); /* */) {
if (*itt == "d") {
itt = l.erase(itt);
} else {
++itt;
}
// You cannot safely access *itt here because it might be l.end()
}
答案 1 :(得分:1)
两个问题。第一:
it - l.begin()
列表迭代器不是随机访问,因此它们没有定义operator-()
,原因很明显,这将是一项昂贵的操作。如果你想这样做,你必须这样做:
std::distance(l.begin(), it);
第二,行:
itt = l.erase(itt);
表示最后一个元素会导致itt
成为l.end()
,因此后续的itt++
是未定义的行为。你需要做的是有条件地增加迭代器:
for (std::list<string>::iterator itt = l.begin(); itt != l.end(); /* nothing */) {
if (*itt == "d") {
itt = l.erase(itt);
}
else {
// cout stuff here
++itt;
}
}