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

mem_fun with template function

P: n/a
I have a member function that acts on an object. I would also like to
have a member function that acts on a container of such objects,
using std::for_each. I tried:

#include <algorithm>
#include <functional>

struct bar {
template<typename T> void foo(T const &);
template<typename InIt> void foo(InIt begin, InIt end)
{ std::for_each(begin, end, foo); }
};

but got a compiler error (at the point of calling foo, not at the point
of declaration) because 'foo' was a pointer to member function, rather
than a pointer to function. So I tried:
std::for_each(begin, end, std::mem_fun(&foo));
but got the error:
Could not find a match for std::mem_fun<S,T>(void (bar::*)(const T &))

Finally I tried:
std::for_each(begin, end, std::mem_fun(&foo<typename InIt::value_type>));
but got an ICE.

What is the correct usage?

I have in fact solved the problem with:
{ for (; begin != end; ++begin) fo(*begin); }
but would like to know if it is possible with for_each anyway.
Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
In article <84**************************@posting.google.com >,
ol*****@inspire.net.nz (Old Wolf) wrote:
I have a member function that acts on an object. I would also like to
have a member function that acts on a container of such objects,
using std::for_each. I tried:

#include <algorithm>
#include <functional>

struct bar {
template<typename T> void foo(T const &);
template<typename InIt> void foo(InIt begin, InIt end)
{ std::for_each(begin, end, foo); }
};

but got a compiler error (at the point of calling foo, not at the point
of declaration) because 'foo' was a pointer to member function, rather
than a pointer to function. So I tried:
std::for_each(begin, end, std::mem_fun(&foo));
but got the error:
Could not find a match for std::mem_fun<S,T>(void (bar::*)(const T &))

Finally I tried:
std::for_each(begin, end, std::mem_fun(&foo<typename InIt::value_type>));
but got an ICE.

What is the correct usage?
struct bar {
template < typename T >
void foo(const T) const { /* whatever */ }
template < typename InIt >
void foo(InIt begin, InIt end) const {
for_each(begin, end,
bind1st(mem_fun(&bar::foo<typename InIt::value_type>) ,this));
}
};

Note that foo no longer takes a 'const T&', it takes a 'const T'. This
is because of a problem with the language that you can't take a
reference to a reference. I think this is scheduled to be fixed in the
next version of C++?

I have in fact solved the problem with:
{ for (; begin != end; ++begin) foo(*begin); }
but would like to know if it is possible with for_each anyway.


I would write it:
{ while (begin != end) foo( *begin++ ); }
Jul 22 '05 #2

P: n/a
"Old Wolf" <ol*****@inspire.net.nz> wrote in message
news:84**************************@posting.google.c om...
I have a member function that acts on an object. I would also like to
have a member function that acts on a container of such objects,
using std::for_each. I tried:

#include <algorithm>
#include <functional>

struct bar {
template<typename T> void foo(T const &);
template<typename InIt> void foo(InIt begin, InIt end)
{ std::for_each(begin, end, foo); }
};

but got a compiler error (at the point of calling foo, not at the point
of declaration) because 'foo' was a pointer to member function, rather
than a pointer to function. So I tried:
std::for_each(begin, end, std::mem_fun(&foo));
but got the error:
Could not find a match for std::mem_fun<S,T>(void (bar::*)(const T &))

Finally I tried:
std::for_each(begin, end, std::mem_fun(&foo<typename InIt::value_type>)); but got an ICE.

What is the correct usage?

I have in fact solved the problem with:
{ for (; begin != end; ++begin) fo(*begin); }
but would like to know if it is possible with for_each anyway.


This looks like a case where attempting to only use the functionality
provided by the standard library is difficult, if not impossible. You first
create an instance of mem_fun1_t<void, bar, const T&>. You need to bind the
first argument of the mem_fun1_t's operator() to this, so you need to create
a binder1st, which will expose an operator() which will declare a const T&&,
which is not allowed. The boost library may make this easier. However, I
wouldn't worry about it, because the for loop is much clearer.

--
David Hilsee
Jul 22 '05 #3

P: n/a
On Mon, 16 Aug 2004 01:31:41 GMT, "Daniel T."
<po********@eathlink.net> wrote:
struct bar {
template < typename T >
void foo(const T) const { /* whatever */ }
template < typename InIt >
void foo(InIt begin, InIt end) const {
for_each(begin, end,
bind1st(mem_fun(&bar::foo<typename InIt::value_type>) ,this));
}
};

Note that foo no longer takes a 'const T&', it takes a 'const T'. This
is because of a problem with the language that you can't take a
reference to a reference. I think this is scheduled to be fixed in the
next version of C++?


The standard library technical report (due soon) includes
std::tr1::bind and std::tr1::mem_fn which sidestep these problems
without language changes. e.g.

bind(&bar::foo<typename InIt::value_type>, this)

and foo can take a reference parameter now.

Tom
Jul 22 '05 #4

P: n/a
"Daniel T." <po********@eathlink.net> wrote:
ol*****@inspire.net.nz (Old Wolf) wrote:
I have in fact solved the problem with:
{ for (; begin != end; ++begin) foo(*begin); }
but would like to know if it is possible with for_each anyway.


I would write it:
{ while (begin != end) foo( *begin++ ); }


But that causes an object to be created and destroyed every time
around the loop (the return-value from operator++ I mean), if
the iterator is a class type? (as it usually will be in my
project, since this gets called for deques).
Jul 22 '05 #5

P: n/a
ol*****@inspire.net.nz (Old Wolf) wrote:
"Daniel T." <po********@eathlink.net> wrote:
ol*****@inspire.net.nz (Old Wolf) wrote:
I have in fact solved the problem with:
{ for (; begin != end; ++begin) foo(*begin); }
but would like to know if it is possible with for_each anyway.


I would write it:
{ while (begin != end) foo( *begin++ ); }


But that causes an object to be created and destroyed every time
around the loop (the return-value from operator++ I mean), if
the iterator is a class type? (as it usually will be in my
project, since this gets called for deques).


*If* profiling shows this to be a performance hit, then change it...
What is being created is an iterator, not exactly the largest object in
the world.
Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.