int main()
{
std::vector<int> array{1, 2, 3, 4, 5};
for(auto i = array.begin(); i != array.end();) {
if(*i == 2 || *i == 5) {
i = array.erase(i);
} else {
i++;
}
}
}
int main()
{
std::vector<int> array{1, 2, 3, 4, 5};
for(auto i = array.begin(); i != array.end(); i++) {
if(*i == 2 || *i == 5) {
i-- = array.erase(i);
}
}
}
这两种形式是否相同?我可以使用一个或另一个来解决问题吗? (即对于各种对象,例如链表?)。
答案 0 :(得分:4)
这一个,形式3:
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> array{1, 2, 3, 4, 5};
auto is_2_or_5 = [](int i) {
return i == 2 || i == 5;
};
array.erase(std::remove_if(array.begin(),
array.end(),
is_2_or_5),
array.end());
}
答案 1 :(得分:3)
i-- = array.erase(i);
在C++11
和C++11
之前都有未定义的行为。
有关更多血腥的详细信息,请查看:
即使它被很好地定义,我也不会将i--
构造用于除独立表达式之外的任何其他内容。很难理解发生了什么。
答案 2 :(得分:2)
表格2 已损坏。
i-- = array.erase(i);
让我们打破它;
i--
这将返回i
的副本,然后递减i
。
array.erase(i)
这会删除i
处的元素,然后将迭代器返回到元素之后。
(i--) = (array.erase(i));
这会将array.erase(i)
的结果分配给i--
返回的副本。
在C ++ 11之前肯定会有一个额外的复杂因素,你不知道在调用array.erase(i)
之前或之后是否完成了减量,这可能是未定义的行为。实验上,GCC在擦除之前执行递减,因此您最终会删除错误的元素。
编写(几乎)等效代码可能会有所帮助:
auto j = i;
--i; // Here??
auto k = array.erase(i);
--i; // Or here?
j = k;
如果您想这样做,请将其写为:
const auto j = i;
--i;
array.erase(j);
这使你更清楚自己在做什么。