Boost logo

Boost :

From: gregod_at_[hidden]
Date: 2001-04-20 09:16:22


--- In boost_at_y..., "Dale Peakall" <dale.peakall_at_b...> wrote:
> Bill Kempf wrote:
> > As pointed out in another post, member functions can be trivially
> > changed into function objects eliminating the need for direct
support
> > by any_function. In early discussions it was seen as wasted
> > duplication of effort to address this in a "callback" class when
> > standard adapter classes were also in the pipe (i.e.
boost::bind).
>
> I wouldn't class myself as an expert at these things, but I at
least
> thought I had a reasonable idea, and I can't see how you can
"trivially"
> convert a class, member function pair into a callback (at least on
my
> totally broken MSVC compiler - no void return's, no partial
specialisation).
>
> I've spent the last day or so working at a solution that I can use
until
> the absolutely fab boost::bind arrives and have totally failed.
I'd have
> thought this put the problem beyond the realm of "trivial".
>
> Any news on boost::bind?

If boost::bind is too far off, perhaps it would be best if Boost
supplied a bind() for this - at least until a more powerful version
of bind is accepted.

The code at the end should handle what you need - just copy 'n'
paste for however many arguments you need. I haven't tested under
VC++, but it should work.

        Doug

template<typename Client, typename R, typename T1>
struct call_member1
{
public:
  call_member1(Client* c, R (Client::*m)(T1)) : client(c), member(m)
{}
  call_member1(const call_member1& other) :
    client(other.client), member(other.member)
  {}

  R operator()(T1 a1)
  {
    return (client->*member)(a1);
  }

private:
  Client* client;
  R (Client::*member)(T1);
};

template<typename Client, typename T1>
struct call_member1_void
{
public:
  call_member1_void(Client* c, void (Client::*m)(T1)) : client(c),
member(m) {}
  call_member1_void(const call_member1_void& other) :
    client(other.client), member(other.member)
  {}

  void operator()(T1 a1)
  {
    (client->*member)(a1);
  }

private:
  Client* client;
  void (Client::*member)(T1);
};

template<typename>
struct call_member1_selector
{
  template<typename Client, typename R, typename T1>
  struct caller
  {
    typedef call_member1<Client, R, T1> type;
  };
};

template<>
struct call_member1_selector<void>
{
  template<typename Client, typename, typename T1>
  struct caller
  {
    typedef call_member1_void<Client, T1> type;
  };
};

template<typename Client, typename R, typename T1>
inline typename call_member1_selector<R>::template caller<Client, R,
T1>::type
bind(Client* client, R (Client::*member)(T1))
{
  typedef typename call_member1_selector<R>::
    template caller<Client, R, T1>::type caller;

  return caller(client, member);
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk