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

|
Related Articles |
|
|