mem_fun with template function



 DEVELOP > c-Plus-Plus > mem_fun with template function

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "Old Wolf"
Date: 15 Aug 2004 06:13:00 PM
Object: mem_fun with template function
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.
.

User: "David Hilsee"

Title: Re: mem_fun with template function 15 Aug 2004 09:08:27 PM
"Old Wolf" <oldwolf@inspire.net.nz> wrote in message
news:843a4f78.0408151512.4420cea8@posting.google.com...

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
.

User: "Daniel T."

Title: Re: mem_fun with template function 15 Aug 2004 08:31:41 PM
In article <843a4f78.0408151512.4420cea8@posting.google.com>,
(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++ ); }
.
User: "Old Wolf"

Title: Re: mem_fun with template function 16 Aug 2004 11:07:29 PM
"Daniel T." <postmaster@eathlink.net> wrote:

oldwolf@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).
.
User: "Daniel T."

Title: Re: mem_fun with template function 17 Aug 2004 06:09:45 AM
(Old Wolf) wrote:

"Daniel T." <postmaster@eathlink.net> wrote:

(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.
.


User: "tom_usenet"

Title: Re: mem_fun with template function 16 Aug 2004 07:19:30 AM
On Mon, 16 Aug 2004 01:31:41 GMT, "Daniel T."
<postmaster@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
.



  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER