Topic: STL Member Function Adapters


Author: "Leo Goodstadt" <100752.1272@compuserve.com>
Date: 1997/08/19
Raw View
Two questions on STL Member Function Adapters:
1) A matter of efficiency. Is it impossible to have inlining with the
indirect function call?

2) Just browsing through Bjarne Stroustrup's 3rd edition of the C++
programming (entertaining bedside reading) language when I came across the
following sentence:

"The standard library need not deal with member functions taking more than
one argument because no standard library algorithm takes a function with
more than two arguments as operands." p.521 end of 18.4.4.2

I take it this does not mean I cannot define my own member function
adaptors taking functions with more than one argument. There are indeed no
standard library algorithms taking functions with more than two arguments.
In fact the only ones which take binary functions I can seem to find use
them for comparisons, which are I suspect of less utility for member
functions. The only example in the book with a member function adaptor on
function taking an argument is one where bind2nd is used to "adapt" it into
a unary function:

  for_each(ls.begin(), ls.end(), bind2nd(mem_fun(&shape::rotate), angle)


What is to prevent me from writing
  for_each(ls.begin(), ls.end(), bind2nd3rd(mem_fun(&shape::rotate), angle,
centre)
(with my own bind2nd3rd of course)?

Actually, the following might be even simpler:

template <class S, class T, class ConstParam1, class ConstParam2>
class mem_fun2_t : public std::unary_function<T*, S> {
public:
  explicit mem_fun2_t(S (T::*pf)(ConstParam1, ConstParam2), ConstParam1 p1,
ConstParam2 p2)
     : f(pf), P1(p1), P2(p2) {}
  S operator()(T* p) const { return (p->*f)(P1, P2); }
private:
  ConstParam1 P1;
  ConstParam2 P2;
  S (T::*f)(ConstParam1, ConstParam2);
};

// with a similar class for taking void (T::*pf)(P1, P2)

template <class S, class T, class P1, class P2>
inline mem_fun2_t<S,T,P1,P2> mem_fun2(S (T::*f)(P1, P2), P1 p1, P2 p2) {
  return mem_fun2_t<S,T,P1,P2>(f, p1, p2);
}

  for_each(ls.begin(), ls.end(), mem_fun2(&shape::rotate, angle, centre));

Seems to work for Borland c++ 5.02.

P.S. The innocent looking

template<class T> T* delete_ptr(T* p) { delete p; return 0;}

produced the following:
Access violation occurred at 0x...: Attempt to access 0x....
Unknown error
I presume Borland International do not know better than the great man
himself. At the least they should have given a slightly more useful
diagnostic message  :->
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1997/08/20
Raw View
"Leo Goodstadt" <100752.1272@compuserve.com> wrote:

: 2) Just browsing through Bjarne Stroustrup's 3rd edition of the C++
: programming (entertaining bedside reading) language when I came across the
: following sentence:

: "The standard library need not deal with member functions taking more than
: one argument because no standard library algorithm takes a function with
: more than two arguments as operands." p.521 end of 18.4.4.2

: I take it this does not mean I cannot define my own member function
: adaptors taking functions with more than one argument.

Yes, the library has many examples of ideas which may be extended to
cover less common things.

: What is to prevent me from writing
:   for_each(ls.begin(), ls.end(), bind2nd3rd(mem_fun(&shape::rotate), angle,
: centre)
: (with my own bind2nd3rd of course)?

Nothing.  And bind1st2nd and bind1st3rd, of course.

: P.S. The innocent looking

: template<class T> T* delete_ptr(T* p) { delete p; return 0;}