mem_fun with template function

Discussion in 'C++' started by Old Wolf, Aug 16, 2004.

  1. Old Wolf

    Old Wolf Guest

    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.
    Old Wolf, Aug 16, 2004
    #1
    1. Advertising

  2. Old Wolf

    Daniel T. Guest

    In article <>,
    (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++ ); }
    Daniel T., Aug 16, 2004
    #2
    1. Advertising

  3. Old Wolf

    David Hilsee Guest

    "Old Wolf" <> wrote in message
    news:...
    > 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
    David Hilsee, Aug 16, 2004
    #3
  4. Old Wolf

    tom_usenet Guest

    On Mon, 16 Aug 2004 01:31:41 GMT, "Daniel T."
    <> 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
    tom_usenet, Aug 16, 2004
    #4
  5. Old Wolf

    Old Wolf Guest

    "Daniel T." <> 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).
    Old Wolf, Aug 17, 2004
    #5
  6. Old Wolf

    Daniel T. Guest

    (Old Wolf) wrote:

    > "Daniel T." <> 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.
    Daniel T., Aug 17, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. k0tic
    Replies:
    1
    Views:
    574
    Alf P. Steinbach
    Sep 4, 2003
  2. Maitre Bart

    STL custom mem_fun

    Maitre Bart, Feb 10, 2004, in forum: C++
    Replies:
    2
    Views:
    583
    Maitre Bart
    Feb 11, 2004
  3. Robbie Hatley

    Problem using mem_fun.

    Robbie Hatley, Oct 24, 2004, in forum: C++
    Replies:
    2
    Views:
    1,197
    Robbie Hatley
    Oct 25, 2004
  4. Mr X
    Replies:
    9
    Views:
    615
    Mike Wahler
    Jan 19, 2005
  5. Ioannis Vranos

    mem_fun vs mem_fun_ref

    Ioannis Vranos, Mar 17, 2005, in forum: C++
    Replies:
    13
    Views:
    7,000
    Pete Becker
    Mar 17, 2005
Loading...

Share This Page