Replacing boost::function and boost::bind with Templates

328 views Asked by At

I'm attempting to remove boost libraries from my code. I don't have std::function, and i'm working with C++98, not c++11. I still need to store a vector of simple void Funcs() from different classes.

I'm using a simple template to get the Class and the instance of the function. But i'd like to replace the need for boost::function and boost::bind.

class App
{
public:
   App();

   template<class T>
   static void AddLoopFunc(void (T::*func)(), T* instance)
   {
       loop_funcs.push_back(boost::bind(func, instance));
   }

   static std::vector< boost::function<void()> > loop_funcs;
};

adding a function to the loop

App::AddLoopFunc(&MyClass::Loop, this);
2

There are 2 answers

1
Maxim Egorushkin On

boost::function and boost::bind are available in C++98, no need to replace them.

0
n. m. could be an AI On

Let's make some type-erasing adaptor for a member function of any class with a given signature.

struct dummy
{
    void func() {};
};

typedef void (dummy::*dummyfunc)();

template <class Obj>
void adapt_ptr_mem_func_0(void* obj, dummyfunc func)
{
    void (Obj::*realfunc)() = reinterpret_cast<void (Obj::*)()>(func);
    Obj* realobj = reinterpret_cast<Obj*>(obj);
    (realobj->*realfunc)();
}

You can call a pointer-to-member-function of any class with this. Not in a type safe manner but we will hide this behind a type-safe store front in a moment.

class callback
{
    void (dummy::*func)();
    void* obj;
    void (*adaptor)(void*, void (dummy::*)());
  public:
    template <class Obj>
    callback(Obj* obj, void (Obj::*func)(void)) :
        obj(obj), func(reinterpret_cast<dummyfunc>(func)),
        adaptor(adapt_ptr_mem_func_0<Obj>) {}

    void operator()()
    {
        adaptor(obj, func);
    }
};

The callback constructor accepts an object obj_ and a pointer-to-member-function func_, and makes a type-erased function object that, when called, calls (obj->*func)().

Testing:

struct Moo
{
    int m;
    Moo (int m) : m(m) {};
    void doit() { std::cout << m << "\n"; }
};

int main()
{
    Moo moo(42);
    callback c(&moo, &Moo::doit);
    c();
};