Boost logo

Boost :

From: Geurt Vos (G.Vos_at_[hidden])
Date: 2001-04-20 08:26:29


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

Hi Dale,
First, I think here 'trivial' refers to usage of bind, not
its implementation. So _when_ bind is there, _then_ it will
be trivial.

Then, I don't know about bind() and all (the 'who' and 'when'
parts). Also, I don't know what decisions, etc. were made
for it, but here's an idea of how it could be done:

template <class Impl, typename Result, typename Param1>
class binder_1 {
public:
    typedef Result (Impl::*FuncPtr)(Param1);

    binder_1(Impl &inst, FuncPtr func):
        instance(inst), funcPtr(func)
    { }

    Result operator()(Param1 param1) const
    {
        return (instance.*funcPtr)(param1);
    }

private:
    Impl &instance;
    FuncPtr funcPtr;
};

template <class Impl, typename Result, typename Param1>
binder_1<Impl,Result,Param1> bind(Impl &inst, Result (Impl::*func)(Param1))
{
    return binder_1<Impl,Result,Param1>(inst,func);
}

class Test {
public:
    int SomeFunc(int i)
    {
        return i;
    }
};

int main()
{
    Test test;
    boost::any_function<int,int> a;
    a = bind(test,&Test::SomeFunc);
    a(100);
}

There are still many problems. For instance, it doesn't take 'const'
functions, and for MSVC 6 'void' returns won't work. I think to solve
the last one you'll need to use full templ spec inside binder_1:

template <class Impl, typename Result, typename Param1>
class binder_1 {
    template <typename>
    class real_binder {
        // ...
    };
    template <>
    class real_binder<void> {
        // ...
    };

    typedef real_binder<Result> real_binder_1;
};

now bind() should return binder_1<...>::real_binder_1 instead.

HTH,
Geurt


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