|
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