Connecting Tech Pros Worldwide Forums | Help | Site Map

mem_fun with template function

Old Wolf
Guest
 
Posts: n/a
#1: Jul 22 '05
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.

Daniel T.
Guest
 
Posts: n/a
#2: Jul 22 '05

re: mem_fun with template function


In article <843a4f78.0408151512.4420cea8@posting.google.com >,
oldwolf@inspire.net.nz (Old Wolf) wrote:
[color=blue]
> 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?[/color]

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++?

[color=blue]
> 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.[/color]

I would write it:
{ while (begin != end) foo( *begin++ ); }
David Hilsee
Guest
 
Posts: n/a
#3: Jul 22 '05

re: mem_fun with template function


"Old Wolf" <oldwolf@inspire.net.nz> wrote in message
news:843a4f78.0408151512.4420cea8@posting.google.c om...[color=blue]
> 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[/color]
InIt::value_type>));[color=blue]
> 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.[/color]

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


tom_usenet
Guest
 
Posts: n/a
#4: Jul 22 '05

re: mem_fun with template function


On Mon, 16 Aug 2004 01:31:41 GMT, "Daniel T."
<postmaster@eathlink.net> wrote:
[color=blue]
>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++?[/color]

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
Old Wolf
Guest
 
Posts: n/a
#5: Jul 22 '05

re: mem_fun with template function


"Daniel T." <postmaster@eathlink.net> wrote:[color=blue]
> oldwolf@inspire.net.nz (Old Wolf) wrote:
>[color=green]
> > 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.[/color]
>
> I would write it:
> { while (begin != end) foo( *begin++ ); }[/color]

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).
Daniel T.
Guest
 
Posts: n/a
#6: Jul 22 '05

re: mem_fun with template function


oldwolf@inspire.net.nz (Old Wolf) wrote:
[color=blue]
> "Daniel T." <postmaster@eathlink.net> wrote:[color=green]
> > oldwolf@inspire.net.nz (Old Wolf) wrote:
> >[color=darkred]
> > > 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.[/color]
> >
> > I would write it:
> > { while (begin != end) foo( *begin++ ); }[/color]
>
> 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).[/color]

*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.
Closed Thread