By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,760 Members | 1,630 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,760 IT Pros & Developers. It's quick & easy.

std::list remove element mid iteration

P: n/a
The situation is that a std::list<std::set<std::string is being
iterated through. Upon certain criteria some sets become empty. I need
to remove the empty sets from the list.

Is it safe to iterate through a list and call list::erase( iterator )
in mid iteration?
Dec 20 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Christopher wrote:
The situation is that a std::list<std::set<std::string is being
iterated through. Upon certain criteria some sets become empty. I need
to remove the empty sets from the list.

Is it safe to iterate through a list and call list::erase( iterator )
in mid iteration?
Well, you can use

struct set_is_empty
{
bool operator()(const std::set& s) const { return s.empty(); }
};

std::erase(std::remove_if(l.begin(), l.end(), set_is_empty());

or else, the canonical iteration for this list is:

for (it = l.begin(); it != l.end(); )
if (it->empty())
it = l.erase(it);
else
++it;
Dec 20 '07 #2

P: n/a
red floyd wrote:
Christopher wrote:
>The situation is that a std::list<std::set<std::string is being
iterated through. Upon certain criteria some sets become empty. I need
to remove the empty sets from the list.

Is it safe to iterate through a list and call list::erase( iterator )
in mid iteration?

Well, you can use

struct set_is_empty
{
bool operator()(const std::set& s) const { return s.empty(); }
};

std::erase(std::remove_if(l.begin(), l.end(), set_is_empty());
crap. That should be:

l.erase(std::remove_if(l.begin(), l.end(), set_is_empty()), l.end());
>
or else, the canonical iteration for this list is:

for (it = l.begin(); it != l.end(); )
if (it->empty())
it = l.erase(it);
else
++it;
Dec 20 '07 #3

P: n/a
On Dec 20, 2:10 am, red floyd <no.s...@here.dudewrote:
Christopher wrote:
The situation is that a std::list<std::set<std::string is being
iterated through. Upon certain criteria some sets become empty. I need
to remove the empty sets from the list.
Is it safe to iterate through a list and call list::erase( iterator )
in mid iteration?
Well, you can use
struct set_is_empty
{
bool operator()(const std::set& s) const { return s.empty(); }
};
std::erase(std::remove_if(l.begin(), l.end(), set_is_empty());
Which could be unnecessarily expensive. In the case of
std::list, the canonical form is:

l.remove_if( set_is_empty() ) ;

However, the original poster said that sets "become" empty
during his iteration, so this can't be used.
or else, the canonical iteration for this list is:
for (it = l.begin(); it != l.end(); )
if (it->empty())
it = l.erase(it);
else
++it;
Adopted to his case, you'd add braces and put the if at the end
of the loop. (Also, I'd write this with a while, rather than a
for. Something like:

std::list<...>::iterator iter = l.begin() ;
while ( iter != l.end() ) {
// processing...
if ( iter->empty() ) {
iter = l.erase( iter ) ;
} else {
++ iter ;
}
}

I'd prefer even more if that if could be replaced with a ?: on
the right side of an assignment, since the most important aspect
here is the update of the iterator, and not how it's being
updated, but I can't think of a nice way of doing this off hand.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orient閑 objet/
Beratung in objektorientierter Datenverarbeitung
9 place S閙ard, 78210 St.-Cyr-l'蒫ole, France, +33 (0)1 30 23 00 34
Dec 20 '07 #4

P: n/a
On 12月20日, 下午5时40分, James Kanze <james.ka...@gmail.comwrote:
On Dec 20, 2:10 am, red floyd <no.s...@here.dudewrote:
Christopher wrote:
The situation is that a std::list<std::set<std::string is being
iterated through. Upon certain criteria some sets become empty. I need
to remove the empty sets from the list.
Is it safe to iterate through a list and call list::erase( iterator )
in mid iteration?
Well, you can use
struct set_is_empty
{
bool operator()(const std::set& s) const { return s.empty(); }
};
std::erase(std::remove_if(l.begin(), l.end(), set_is_empty());

Which could be unnecessarily expensive. In the case of
std::list, the canonical form is:

l.remove_if( set_is_empty() ) ;
That is what I found in MSDN,
remove_if is a STL algorithm which removes all elements from the range
(First,Last) that cause the predicate to return true. It returns an
iterator equal to Last - n, where n = number of elements removed. The
last n elements of the range have undefined values. The size of the
container remains the same.
But there is a method named remove_if in std::list.
template<class Predicate>
void remove_if(
Predicate _Pred
)
Erases elements from a list for which a specified predicate is
satisfied.
I didn't know there is a method named remove_if in the std::list. Can
any one told me why there is no similar method in vector ?

Thanks in advance,:)
Dec 20 '07 #5

P: n/a
On Dec 20, 12:40 pm, "cgsp...@gmail.com" <cgsp...@gmail.comwrote:
On 12鏈20鏃, 涓嬪崍5鏃40鍒, James Kanze <james.ka...@gmail.comwrote:
On Dec 20, 2:10 am, red floyd <no.s...@here.dudewrote:
Christopher wrote:
The situation is that a std::list<std::set<std::string is being
iterated through. Upon certain criteria some sets become empty. I need
to remove the empty sets from the list.
Is it safe to iterate through a list and call list::erase( iterator )
in mid iteration?
Well, you can use
struct set_is_empty
{
bool operator()(const std::set& s) const { return s.empty(); }
};
std::erase(std::remove_if(l.begin(), l.end(), set_is_empty());
Which could be unnecessarily expensive. In the case of
std::list, the canonical form is:
l.remove_if( set_is_empty() ) ;
That is what I found in MSDN,
remove_if is a STL algorithm which removes all elements from the range
(First,Last) that cause the predicate to return true. It returns an
iterator equal to Last - n, where n = number of elements removed. The
last n elements of the range have undefined values. The size of the
container remains the same.
But there is a method named remove_if in std::list.
template<class Predicate>
void remove_if(
Predicate _Pred
)
Erases elements from a list for which a specified predicate is
satisfied.
I didn't know there is a method named remove_if in the std::list. Can
any one told me why there is no similar method in vector ?
Because you don't need it, and it's not directly supported by
the underlying data structure.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orient茅e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S茅mard, 78210 St.-Cyr-l'脡cole, France, +33 (0)1 30 23 00 34
Dec 20 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.