Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > remove_if and member function pointers

Reply
Thread Tools

remove_if and member function pointers

 
 
Jon Rea
Guest
Posts: n/a
 
      11-16-2006
Hello all,

Sorry if this is long, but I wanted to be specific...

Can anyone shed any light on the following errors in the context of the
following example code:

cullMethod1(); // compiles, but not what we want - we cant access
m_Exclustions

cullMethod2(); // fine but long-winded and causes many array re-allocations

cullMethod3(); // doen't compile!

i.e. How do you pass a member function to std functions.

Many thanks,
Jon Rea


////////////////////////////////////////////////////
// Begin example code ..

#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

class Bond
{
public:
Bond( int _i, int _j )
{
i = _i;
j = _j;
}
Bond()
{
i = rand();
j = rand();
}
int i;
int j;
};

class MyBase
{
public:
virtual void Setup()
{
int bigNumber = 10000;
for( int i = 0; i < bigNumber; i++ )
{
m_Bonds.push_back( Bond() ); // add lots of random "bonds"
}
}
protected:
std::vector<Bond> m_Bonds;
};

bool mySpecialSelectionFunction( Bond& _b )
{
return _b.i == 47;
}

class MyDerived : public MyBase
{
public:
virtual void Setup()
{
MyBase::Setup();

m_Exclustions.push_back(Bond(43,21));
m_Exclustions.push_back(Bond(12,14));
m_Exclustions.push_back(Bond(1,41));

// Remove all instances of the definitions in m_Exclustions from the
base class list.

// Call ONE of these in real code:
cullMethod1(); // compiles, but not what we want - we cant access
m_Exclustions
cullMethod2(); // fine but long-whinded and causes many array
re-allocations
cullMethod3(); // doen't compile!
}

bool Matches( Bond& bond )
{
for( size_t k = 0; k < m_Exclustions.size(); k++ )
{
if( ( bond.i == m_Exclustions[k].i && bond.j == m_Exclustions[k].j ) ||
( bond.j == m_Exclustions[k].i && bond.i == m_Exclustions[k].j ) )
{
return true;
}
}
return false;
}

void cullMethod1()
{
m_Bonds.erase( remove_if( m_Bonds.begin(), m_Bonds.end(),
mySpecialSelectionFunction ), m_Bonds.end() );
}

void cullMethod2()
{
for( size_t i = 0; i < m_Bonds.size(); /*blank*/ )
{
if( Matches( m_Bonds[i] ) )
{
m_Bonds.erase(m_Bonds.begin()+i);
}
else
{
i++;
}
}
}

void cullMethod3()
{
// Illegal operand on bound member function expression ...
//m_Bonds.erase( remove_if( m_Bonds.begin(), m_Bonds.end(), &Matches
), m_Bonds.end() );

// Term does not evaluare to a function taking 1 arguments ...
//m_Bonds.erase( remove_if( m_Bonds.begin(), m_Bonds.end(),
&MyDerived::Matches ), m_Bonds.end() );

// Term does not evaluare to a function taking 1 arguments ...
//m_Bonds.erase( remove_if( m_Bonds.begin(), m_Bonds.end(),
std::mem_fun_ref(&MyDerived::Matches) ), m_Bonds.end() );
}

protected:
std::vector<Bond> m_Exclustions;
};

int _tmain(int argc, _TCHAR* argv[])
{
MyDerived bob;
bob.Setup();
return 0;
}
 
Reply With Quote
 
 
 
 
Daniel T.
Guest
Posts: n/a
 
      11-17-2006
In article <>, Jon Rea <>
wrote:

> Hello all,
>
> Sorry if this is long, but I wanted to be specific...
>
> Can anyone shed any light on the following errors in the context of the
> following example code:
>
> cullMethod1(); // compiles, but not what we want - we cant access
> m_Exclustions
>
> cullMethod2(); // fine but long-winded and causes many array re-allocations
>
> cullMethod3(); // doen't compile!
>
> i.e. How do you pass a member function to std functions.


First change the signature for Matches:

bool Matches(Bond bond) const
{
...
}

Then you can:

void cullMethod1()
{
m_Bonds.erase(remove_if(m_Bonds.begin(), m_Bonds.end(),
bind1st(mem_fun(&MyDerived::Matches), this)), m_Bonds.end());
}

--
To send me email, put "sheltie" in the subject.
 
Reply With Quote
 
 
 
 
Jon Rea
Guest
Posts: n/a
 
      11-17-2006
Daniel T. wrote:
> In article <>, Jon Rea <>
> wrote:
>
>> Hello all,
>>
>> Sorry if this is long, but I wanted to be specific...
>>
>> Can anyone shed any light on the following errors in the context of the
>> following example code:
>>
>> cullMethod1(); // compiles, but not what we want - we cant access
>> m_Exclustions
>>
>> cullMethod2(); // fine but long-winded and causes many array re-allocations
>>
>> cullMethod3(); // doen't compile!
>>
>> i.e. How do you pass a member function to std functions.

>
> First change the signature for Matches:
>
> bool Matches(Bond bond) const
> {
> ...
> }
>
> Then you can:
>
> void cullMethod1()
> {
> m_Bonds.erase(remove_if(m_Bonds.begin(), m_Bonds.end(),
> bind1st(mem_fun(&MyDerived::Matches), this)), m_Bonds.end());
> }
>


Thanks for the reply. Thats better!

What though if I had to use:
bool Matches(BIG_Bond& bond) const;
because copying a 'BIG_Bond' is an expensive operation.

Cheers,
Jon
 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      11-18-2006
In article <>, Jon Rea <> wrote:

> Daniel T. wrote:
> > In article <>, Jon Rea <>
> > wrote:
> >
> >> Hello all,
> >>
> >> Sorry if this is long, but I wanted to be specific...
> >>
> >> Can anyone shed any light on the following errors in the context of the
> >> following example code:
> >>
> >> cullMethod1(); // compiles, but not what we want - we cant access
> >> m_Exclustions
> >>
> >> cullMethod2(); // fine but long-winded and causes many array re-allocations
> >>
> >> cullMethod3(); // doen't compile!
> >>
> >> i.e. How do you pass a member function to std functions.

> >
> > First change the signature for Matches:
> >
> > bool Matches(Bond bond) const
> > {
> > ...
> > }
> >
> > Then you can:
> >
> > void cullMethod1()
> > {
> > m_Bonds.erase(remove_if(m_Bonds.begin(), m_Bonds.end(),
> > bind1st(mem_fun(&MyDerived::Matches), this)), m_Bonds.end());
> > }
> >

>
> Thanks for the reply. Thats better!
>
> What though if I had to use:
> bool Matches(BIG_Bond& bond) const;
> because copying a 'BIG_Bond' is an expensive operation.


Test first. I would not be surprised to find that the compiler optimized
the copy away if the Matches function doesn't modify the parameter in
any way.

However, if you absolutely *had* to use a const& the you can always
create your own selector and then use:

m_Bonds.erase(remove_if(m_Bonds.begin(), m_Bonds.end(),
selector(&MyDerived::Matches, this)), m_Bonds.end());

Before I show you what "selector" looks like, you may be interested in
how I developed it. I put the above code in as the interface I wished,
and then fixed the compile errors until I had something that ran. After
than, I substituted templated tyeps. QED

template < typename Ret, typename Tp, typename Arg >
struct selector_t : unary_function< Arg, Ret >
{
Ret (Tp::*mfn)(Arg) const;
const Tp* obj;

selector_t(Ret(Tp::*x)(Arg) const, const Tp* y): mfn(x), obj(y) { }

Ret operator()(Arg x) const {
return (obj->*mfn)(x);
}
};

template < typename Ret, typename Tp, typename Arg >
selector_t< Ret, Tp, Arg > selector(Ret(Tp::*x)(Arg) const, Tp* y) {
return selector_t< Ret, Tp, Arg >(x, y);
}

And yes, I double checked. Arg in the above template is a "const Bond&"
and not a "Bond".

--
To send me email, put "sheltie" in the subject.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
static member functions vs. member function pointers paul C++ 8 04-30-2009 11:03 AM
Member function pointers to member functions with default arguments Hamish C++ 3 01-25-2008 06:46 AM
Smart pointers and member function pointers n2xssvv g02gfr12930 C++ 3 11-27-2005 10:51 AM
remove_if and functions overloading marco_segurini C++ 1 04-07-2004 10:42 AM
STL remove_if function Paavo K C++ 1 02-17-2004 05:57 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57