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

call_mem_fun

P: n/a
I have this problem that I meet quite often.

I have a STL container with bunch of whatever objects. The container is
a member of a class that does something. Now, I want to apply a member
of this class to each of the contained objects.

mem_fun will CALL the given member function OF THE CONTAINED object,
but what I want is to call the given method of the CONTAINING object
with the argument being a contained object.

For example:
class Foo
{
public:
....
void doSomething(int i)
{
cout << i << endl;
}

void doSomethingWithEach()
{
for_each<myv.begin(), myv.end(), call_mem_fun(&Foo::doSomething,
this));
}
std::vector<intmyv;
};

NOTE:
call_mem_fun would call "doSomething" and pass to it each int from the
container.

================
So I created the "call_mem_fun" functor, but I'm not sure if I was
reinventing the wheel (just can not believe there is not such thing
already out there somewhere).
Any suggestions?

Nov 15 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
rile wrote:
I have this problem that I meet quite often.

I have a STL container with bunch of whatever objects. The container is
a member of a class that does something. Now, I want to apply a member
of this class to each of the contained objects.

mem_fun will CALL the given member function OF THE CONTAINED object,
but what I want is to call the given method of the CONTAINING object
with the argument being a contained object.

For example:
class Foo
{
public:
...
void doSomething(int i)
{
cout << i << endl;
}

void doSomethingWithEach()
{
for_each<myv.begin(), myv.end(), call_mem_fun(&Foo::doSomething,
this));
}
std::vector<intmyv;
};

NOTE:
call_mem_fun would call "doSomething" and pass to it each int from the
container.

================
So I created the "call_mem_fun" functor, but I'm not sure if I was
reinventing the wheel (just can not believe there is not such thing
already out there somewhere).
Any suggestions?
std::tr1::bind does the same thing (cf. Boost.Bind).

Cheers! --M

Nov 15 '06 #2

P: n/a
I read a bout bind, but I couldn't find the version that does what I
want...

Here is compilable example of the use-case I am looking for; could you
add using "bind" so the code is functionally the same?

Thanks!
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
class Bar
{
public:
Bar(int n) : _n(n) {}
int getN() const { return _n; }
private:
int _n;
};
class Foo
{
public:
Foo()
{
for (int i = 0; i != 10; ++i)
bars.push_back(Bar(i));
}
void printABar(Bar const &bar) const
{
cout << bar.getN() << endl;
}
void printAllBars() const
{
for_each(bars.begin(), bars.end(), call_mem_fun(&Foo::printABar,
this));
}
private:
vector<Barbars;
};

.... in main:

Foo foo;
foo.printAllBars();

(RESULT: it prints out to the console numbers 0 to 9 each in a new
line)
mlimber wrote:
rile wrote:
I have this problem that I meet quite often.

I have a STL container with bunch of whatever objects. The container is
a member of a class that does something. Now, I want to apply a member
of this class to each of the contained objects.

mem_fun will CALL the given member function OF THE CONTAINED object,
but what I want is to call the given method of the CONTAINING object
with the argument being a contained object.

For example:
class Foo
{
public:
...
void doSomething(int i)
{
cout << i << endl;
}

void doSomethingWithEach()
{
for_each<myv.begin(), myv.end(), call_mem_fun(&Foo::doSomething,
this));
}
std::vector<intmyv;
};

NOTE:
call_mem_fun would call "doSomething" and pass to it each int from the
container.

================
So I created the "call_mem_fun" functor, but I'm not sure if I was
reinventing the wheel (just can not believe there is not such thing
already out there somewhere).
Any suggestions?

std::tr1::bind does the same thing (cf. Boost.Bind).

Cheers! --M
Nov 15 '06 #3

P: n/a
"rile" <al******************@gmail.comwrote:
I have this problem that I meet quite often.

I have a STL container with bunch of whatever objects. The container is
a member of a class that does something. Now, I want to apply a member
of this class to each of the contained objects.

mem_fun will CALL the given member function OF THE CONTAINED object,
but what I want is to call the given method of the CONTAINING object
with the argument being a contained object.

For example:
class Foo
{
public:
...
void doSomething(int i)
{
cout << i << endl;
}

void doSomethingWithEach()
{
for_each<myv.begin(), myv.end(), call_mem_fun(&Foo::doSomething,
this));
}
std::vector<intmyv;
};

NOTE:
call_mem_fun would call "doSomething" and pass to it each int from the
container.

================
So I created the "call_mem_fun" functor, but I'm not sure if I was
reinventing the wheel (just can not believe there is not such thing
already out there somewhere).
Any suggestions?
for_each( vec.begin(), vec.end(), bind1st( mem_fun(&Foo::bar), this ) );

--
To send me email, put "sheltie" in the subject.
Nov 15 '06 #4

P: n/a
rile wrote:
>
void doSomethingWithEach()
{
for_each<myv.begin(), myv.end(), call_mem_fun(&Foo::doSomething,
this));
}
bind1st(mem_fun(&Foo::doSomething), this)

If you have TR1 you can make it a bit simpler:
bind(&Foo::doSomething, this, _1)

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Nov 15 '06 #5

P: n/a
Thank you for your replies.

bind1st(mem_fun(&Foo::bar), this))

was what I considered first, but it seems that it won't work if 'bar'
takes reference to argument type (like in my example above). At least
not on MS VS 2005.

well, here is my implementation for those who want to see the diff
(NOTE: I renamed my function "pass_to_mem_fun" because I thought it was
clearer than "call_mem_fun")

template <typename _Result, typename T, typename ArgT>
class pass_to_mem_fun_t : public std::unary_function<ArgT, _Result>
{
public:
explicit pass_to_mem_fun_t(_Result (T::*_Pm)(ArgT), T *pThis)
: _Pmemfun(_Pm), _this(pThis)
{
}

_Result operator()(ArgT _Pleft) const
{ // call function
return (_this->*_Pmemfun)(_Pleft);
}

private:
T *_this;
_Result (T::*_Pmemfun)(ArgT); // the member function pointer
};

template <typename _Result, typename T, typename ArgT>
class pass_to_const_mem_fun_t : public std::unary_function<ArgT,
_Result>
{
public:
explicit pass_to_const_mem_fun_t(_Result (T::*_Pm)(ArgT) const, T
const *pThis)
: _Pmemfun(_Pm), _this(pThis)
{
}

_Result operator()(ArgT _Pleft) const
{ // call function
return (_this->*_Pmemfun)(_Pleft);
}

private:
T const *_this;
_Result (T::*_Pmemfun)(ArgT) const; // the member function pointer
};
template <typename _Result, typename T, typename ArgT>
pass_to_mem_fun_t<_Result, T, ArgT>
pass_to_mem_fun(_Result (T::*pFn)(ArgT), T *pThis)
{
return pass_to_mem_fun_t<_Result, T, ArgT>(pFn, pThis);
}

template <typename _Result, typename T, typename ArgT>
pass_to_const_mem_fun_t<_Result, const T, ArgT>
pass_to_mem_fun(_Result (T::*pFn)(ArgT) const, T const*pThis)
{
return pass_to_const_mem_fun_t<_Result, const T, ArgT>(pFn, pThis);
}

------------

in the foo-bar example I gave, the call would look like this:

for_each(bars.begin(), bars.end(), pass_to_mem_fun(&Foo::printABar,
this));

====

Anyhow, if you see that the "Foo bar" example I posted can be compiled
with any of the standard alternatives, I am eager to know it.

Thank you,

Aleksandar

On Nov 15, 4:13 pm, Pete Becker <p...@versatilecoding.comwrote:
rile wrote:
void doSomethingWithEach()
{
for_each<myv.begin(), myv.end(), call_mem_fun(&Foo::doSomething,
this));
} bind1st(mem_fun(&Foo::doSomething), this)

If you have TR1 you can make it a bit simpler:

bind(&Foo::doSomething, this, _1)

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Nov 15 '06 #6

P: n/a

rile wrote:
I have this problem that I meet quite often.

I have a STL container with bunch of whatever objects. The container is
a member of a class that does something. Now, I want to apply a member
of this class to each of the contained objects.

mem_fun will CALL the given member function OF THE CONTAINED object,
but what I want is to call the given method of the CONTAINING object
with the argument being a contained object.

For example:
class Foo
{
public:
...
void doSomething(int i)
{
cout << i << endl;
}

void doSomethingWithEach()
{
for_each<myv.begin(), myv.end(), call_mem_fun(&Foo::doSomething,
this));
}
std::vector<intmyv;
};

NOTE:
call_mem_fun would call "doSomething" and pass to it each int from the
container.

================
So I created the "call_mem_fun" functor, but I'm not sure if I was
reinventing the wheel (just can not believe there is not such thing
already out there somewhere).
Any suggestions?
As already mentioned: boost's lambda and bind
http://www.boost.org/libs/bind/bind.html

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

template< typename T >
class Foo
{
std::vector< T myv;
public:

void push_back(const T& r_t)
{
myv.push_back( r_t );
}

static void doSomething( const T& t ) {
std::cout << t << std::endl;
}

void doSomethingWithEach() const {
using boost::lambda::_1;
using boost::lambda::bind;
std::for_each( myv.begin(),
myv.end(),
bind(&doSomething, _1) );
}
};

int main()
{
Foo< int foo;
foo.push_back(0);
foo.push_back(1);
foo.push_back(2);

foo.doSomethingWithEach();
}

/*
0
1
2
*/

Nov 15 '06 #7

P: n/a
rile wrote:
>
bind1st(mem_fun(&Foo::bar), this))

was what I considered first, but it seems that it won't work if 'bar'
takes reference to argument type (like in my example above).
In your original example, the member function takes its argument by
value, not by reference.

STL in its original form passes just about everything by value, and
that's a limitation of mem_fun. The bind version works for references.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Nov 15 '06 #8

P: n/a
OK, boost::bind works!

for_each(bars.begin(), bars.end(), boost::bind(&Foo::doSomething, &foo,
_1));

boost::bind does it!

Thank you all for your replies.

Pete Becker wrote:
rile wrote:

bind1st(mem_fun(&Foo::bar), this))

was what I considered first, but it seems that it won't work if 'bar'
takes reference to argument type (like in my example above).

In your original example, the member function takes its argument by
value, not by reference.

STL in its original form passes just about everything by value, and
that's a limitation of mem_fun. The bind version works for references.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Nov 16 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.