removing elements from a std::map with predicate

R

Ralf Goertz

I try tor remove elements from a std::map<int,some_class> for which a
condition depending on the value is met. For containers like vector this
is easy


#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <iterator>

using namespace std;

typedef map<int,int> intmap;

bool is42_m(intmap::value_type w) {
return w.second==42;
}

bool is42_v(const int& w) {
return w==42;
}

int main() {
map<int,int> m;
m[14711]=52;
m[17]=42;
m[4]=17;
vector<int> v;
v.push_back(52);
v.push_back(42);
v.push_back(17);
v.erase(remove_if(v.begin(),v.end(),is42_v),v.end());
//v.erase(remove_if(m.begin(),m.end(),is42_m),m.end());
copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));
cout<<endl;
}


I know that this can't work with a map since remove_if rearranges the
elements of the container which is not possible for a map. But how can I
do that with a map?

Ralf
 
M

Michael DOUBEZ

Ralf said:
I try tor remove elements from a std::map<int,some_class> for which a
condition depending on the value is met. For containers like vector this
is easy


#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <iterator>

using namespace std;

typedef map<int,int> intmap;

bool is42_m(intmap::value_type w) {
return w.second==42;
}

bool is42_v(const int& w) {
return w==42;
}

int main() {
map<int,int> m;
m[14711]=52;
m[17]=42;
m[4]=17;
vector<int> v;
v.push_back(52);
v.push_back(42);
v.push_back(17);
v.erase(remove_if(v.begin(),v.end(),is42_v),v.end());
//v.erase(remove_if(m.begin(),m.end(),is42_m),m.end());
copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));
cout<<endl;
}


I know that this can't work with a map since remove_if rearranges the
elements of the container which is not possible for a map. But how can I
do that with a map?

By hand, something approching could be:

template<class AssociativeContainer, class Predicate>
void erase_if(AssociativeContainer& cont,Predicate pred)
{
//STATIC ASSERT that AssociativeContainer is not const
typedef typename AssociativeContainer::iterator iterator;
iterator it=cont.begin();
const iterator end=cont.end();
while(it!=end);
{
iterator tmp=it++;
if(pred(*tmp))cont.erase(tmp);
}
}
 
R

Ralf Goertz

Michael said:
By hand, something approching could be:

template<class AssociativeContainer, class Predicate>
void erase_if(AssociativeContainer& cont,Predicate pred)
{
//STATIC ASSERT that AssociativeContainer is not const
typedef typename AssociativeContainer::iterator iterator;
iterator it=cont.begin();
const iterator end=cont.end();
while(it!=end);
{
iterator tmp=it++;
if(pred(*tmp))cont.erase(tmp);
}
}

But cont.erase(tmp) invalidates tmp. Does this trick with the using tmp
after „it“ has been increased really work? I always thought that *all*
iterators are invalid after something was erased.
 
R

Ralf Goertz

Michael said:
Ralf said:
Michael DOUBEZ wrote:

But cont.erase(tmp) invalidates tmp. Does this trick with the using
tmp after „it“ has been increased really work? I always thought that
*all* iterators are invalid after something was erased.

They are not invalidated, see requirements on associative containers in
the standard §23.1.2/8:
"[...]the erase members shall invalidate only iterators and references
to the erased elements."

Ah, thanks.
 
M

Michael DOUBEZ

Ralf said:
But cont.erase(tmp) invalidates tmp. Does this trick with the using tmp
after „it“ has been increased really work? I always thought that *all*
iterators are invalid after something was erased.

They are not invalidated, see requirements on associative containers in
the standard §23.1.2/8:
"[...]the erase members shall invalidate only iterators and references
to the erased elements."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top