vector.erase()? [英] vector.erase() ?
问题描述
我有以下代码,其中good_list是CUnits的向量:
int high_cutoff = 10;
vector< CUnit> :: iterator it ;
for(it = good_list.end(); it!= good_list.begin(); - it){
CUnit * ccu = it;
if(ccu-> GetCutoff()> = high_cutoff){
good_list.erase(it);
}
}
不会给出任何错误,但似乎也没有从good_list中正确删除元素
。
上面的代码出了什么问题?
谢谢
BCC写道:
我有以下代码,其中good_list是CUnits的向量:
int high_cutoff = 10;
向量< CUnit>: :iterator it;
for(it = good_list.end(); it!= good_list.begin(); - )){
注意good_list.end( )是一个你不能做很多事情的迭代器。
取消引用它是一个错误。如果你真的需要倒退,那么你可能想要使用反向迭代器。
CUnit * ccu = it;
这可能是无效的转换。一个实现可能会或可能不会
将向量迭代器实现为普通指针。当你已经有一个迭代器时,没有任何理由需要一个指针。只需使用
迭代器。
if(ccu-> GetCutoff()> = high_cutoff){
一个问题是第一次ccu无效。
good_list.erase(it);
''它''在此之后不再有效。我不知道你是否被允许
申请。我不认为这是你的问题,但你应该
可能做这样的事情:
for(/ * init * /; / * cond * /; / * EMPTY!* /)
if(/ * condition * /)
it = good_list.erase(it);
else
++ it;
我用的是++而不是 - ,想你要用反向
迭代器。
}
}
不会给出任何错误,但似乎也没有删除元素
正确来自good_list。
上面的代码有问题吗?
是的。
这是'我推荐的完整替代品(未经测试):
int high_cutoff = 10;
vector< CUnit> :: reverse_iterator it;
for(it = good_list.rbegin(); it!= good_list.rend();){
if(it-> GetCutoff()> ; = high_cutoff){
it = good_list.erase(it);
}
else {
++ it;
}
}
-Kevin
-
我的电子邮件地址有效,但会定期更改。
要联系我,请使用最近发布的地址。
>这是我推荐的完整替代品(未经测试):
int high_cutoff = 10;
vector< CUnit> :: reverse_iterator it;
for(it = good_list.rbegin(); it!= good_list.rend(); ){
if(it-> GetCutoff()> = high_cutoff){
it = good_list.erase(it);
}
else {
+ +它;
}
}
有道理......但一个问题是erase()返回迭代器,而不是
reverse_iterator ...
B
BCC写道:
这是我推荐的全部替代品(未经测试):
int high_cutoff = 10;
vector< CUnit> :: reverse_iterator it;
for(it = good_list.rbegin(); it!= good_list.rend();){
if(it-> GetCutoff()> = high_cutoff){
it = good_list.erase(it);
}
else {
++ it;
}
}
有道理......但有一个问题是erase()返回一个迭代器,而不是一个
reverse_iterator ...... / blockqu ote>
哦,是的......
嗯,实际上,这有点愚蠢。你甚至不想*通过擦除你返回的
迭代器。让他们前进
迭代器 - 没有明显的理由去倒退。
另一方面,如果有*是*的原因你需要向后退,
这对我来说并不明显,那么你可以这样做:
vector< CUnit> :: reverse_iterator tmp = it;
++ tmp;
good_list.erase(it);
it = tmp;
里面的'if''块。
另一个选择是使用算法。 std :: remove_if应该可以工作,我想b $ b。但请记住,它并没有真正删除任何东西,只是
随机播放删除的内容。元素到最后为你擦除()。
-Kevin
-
我的电子邮件地址有效,但是定期更改。
要联系我,请使用最近发布的地址。
I have the following code, where good_list is a vector of CUnits:
int high_cutoff = 10;
vector<CUnit>::iterator it;
for (it = good_list.end(); it != good_list.begin(); --it) {
CUnit* ccu = it;
if (ccu->GetCutoff() >= high_cutoff) {
good_list.erase(it);
}
}
Doesn''t give any errors, but also does not seem to be removing the element
correctly from good_list.
There something wrong with the above code?
Thanks解决方案BCC wrote:
I have the following code, where good_list is a vector of CUnits:
int high_cutoff = 10;
vector<CUnit>::iterator it;
for (it = good_list.end(); it != good_list.begin(); --it) {
Note that good_list.end() is an iterator that you can''t do much with.
Dereferencing it is an error. If you really need to go backwards, you
probably want to use reverse iterators instead.
CUnit* ccu = it;
This may be an invalid conversion. An implementation may or may not
implement vector iterators as plain pointers. There''s not really any
reason to need a pointer when you''ve already got an iterator. Just use
the iterator.
if (ccu->GetCutoff() >= high_cutoff) {
One problem is that ccu isn''t valid the first time through.
good_list.erase(it);
''it'' is no longer valid after this. I don''t know if you are allowed to
apply -- to it. I don''t think this is your problem, but you should
probably do something like this:
for (/* init */; /* cond */; /* EMPTY! */)
if (/* condition */)
it = good_list.erase(it);
else
++it;
I''m using ++ instead of --, figuring that you''ll want to use reverse
iterators.
}
}
Doesn''t give any errors, but also does not seem to be removing the element
correctly from good_list.
There something wrong with the above code?
Yup.
Here''s the entire replacement I''d recommend (untested):
int high_cutoff = 10;
vector<CUnit>::reverse_iterator it;
for (it = good_list.rbegin(); it != good_list.rend(); ) {
if (it->GetCutoff() >= high_cutoff) {
it = good_list.erase(it);
}
else {
++it;
}
}
-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
>Here''s the entire replacement I''d recommend (untested):
int high_cutoff = 10;
vector<CUnit>::reverse_iterator it;
for (it = good_list.rbegin(); it != good_list.rend(); ) {
if (it->GetCutoff() >= high_cutoff) {
it = good_list.erase(it);
}
else {
++it;
}
}
Makes sense.... but one problem is that erase() returns an iterator, not a
reverse_iterator...
Ill see if I can iron it out, thanks!
B
BCC wrote:
Here''s the entire replacement I''d recommend (untested):
int high_cutoff = 10;
vector<CUnit>::reverse_iterator it;
for (it = good_list.rbegin(); it != good_list.rend(); ) {
if (it->GetCutoff() >= high_cutoff) {
it = good_list.erase(it);
}
else {
++it;
}
}
Makes sense.... but one problem is that erase() returns an iterator, not a
reverse_iterator...
Oh, yeah...
Well, that was kind of dumb, actually. You don''t even *want* the
iterator returned by erase of you are going backward. Make them forward
iterators instead - there''s no obvious reason to go backward.
On the other hand, if there *is* a reason that you need to go backward,
which just isn''t apparent to me, then you can do something like this:
vector<CUnit>::reverse_iterator tmp = it;
++tmp;
good_list.erase(it);
it = tmp;
inside the ''if'' block.
Another alternative is to use algorithms. std::remove_if should work, I
think. But remember that it doesn''t really remove anything, it just
shuffles the "removed" elements to the end for you to erase().
-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
这篇关于vector.erase()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!