views:

337

answers:

1

Hello all:

First a disclaimer, I am replacing a bunch of code which uses boost::function and boost::bind. However, I am moving to a codebase which does not allow rtti. I would like to keep using boost but don't know if there is a way around this restriction.

So..., I am trying to mimic some of its functionality, but much more simplified. I have a Callback class:

   template <class Class, typename ReturnType = void> class Callback0 {
   typedef ReturnType (Class::*Method)();

   public:
       Callback0(Class* object, Method method)
           : m_object(object)
           , m_method(method)
       {
          ;
       }

       Callback0(const Callback0& callback)
           : m_object(callback.m_object)
           , m_method(callback.m_method)
       {
          ;
       }

       operator bool() {
           return m_object != 0;
       }

       operator bool() const {
           return m_object != 0;
       }

       ReturnType operator()() {
           return (m_object->*m_method)();
       }

       Callback0<Class, ReturnType>& operator=(const Callback0<Class, ReturnType>& callback) {
           if(this != &callback) {
               m_object = callback.m_object;
               m_method = callback.m_method;
           }

           return *this;
       }

   private:
       Class*   m_object;
       Method   m_method;

};

This allows me to do simple callbacks w/zero parameters:

class Meh {
    public:
        Meh() {;}
        ~Meh() {;}

        void f0() {
            footprint6v("%s\n", __FUNCTION__);
        }
};


static void meh() {
    Meh* m = new Meh;

    Callback0<Meh, void> c0(m, &Meh::f0);

    c0();
}

I would like to be able to assign my callback objects to zero as default parameters like so:

class Wtf {
    public:
        Wtf() : m_callback(0) {;}
        ~Wtf() {;}

        void doSomething(const Callback0<Wtf, void>& callback = 0) {
            m_callback = callback;
        }

    private:
        Callback0<Wtf, void> m_callback;
};

This works when using boost::function as you can do:

class Wtf {
    public:
        Wtf() : m_callback(0) {;}
        ~Wtf() {;}

        void doSomething(const boost::function<void()>& callback = 0) {
            m_callback = callback;
        }

    private:
        boost::function<void()> m_callback;
};

I imagine boost is doing some magic here. I know I can just change the parameter to a pointer rather than a reference but as I said, I am replacing a lot of code and would like to minimize the impact of changing from boost.

Thanks for the help.

+4  A: 

Boost isn't doing anything magic. 0 is just a NULL function pointer for the function pointer constructor.

I would suggest in your case you just provide a default constructor

Callback0() : m_object(NULL), m_method(NULL) {}

And make doSomething look like

void doSomething(const Callback0<Wtf, void>& callback = Callback0<Wtf, void>()) {
Logan Capaldo
Thank you Logan. Just as I got your answer it dawned on me that it was a rather stupid question w/a simple answer. I ended up creating a constructor which takes an integer parameter to get around having to call default constructor explicitly in the function prototype.
ohnnyj
If you think his answer is right, you should mark it correct, so he can get the rep for it.
Tim Keating