0

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 with 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.

VividD
  • 10,456
  • 6
  • 64
  • 111
ohnnyj
  • 53
  • 2
  • 6
  • "...does not allow rtti." seems rather draconian and arbitrary. Can you clarify the reason behind this restriction? If this is a matter of style guidelines, then I'm not sure any part of any foreign dependency can ever fully match the internal style guideline, but that's no reason to disallow the external dependency, so long as your use of it is within the guidelines. If the compiler you are targeting, however, simply does not support that part of C++, well then that's another matter. – SingleNegationElimination Jul 18 '09 at 01:10
  • Thanks for the comment. What I mean to say is, the project is being compiled with the -fno-rtti flag. Thus, no rtti. – ohnnyj Jul 19 '09 at 00:29

1 Answers1

5

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
  • 39,555
  • 5
  • 63
  • 78
  • 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 Jul 18 '09 at 01:04
  • 2
    If you think his answer is right, you should mark it correct, so he can get the rep for it. – Tim Keating Nov 30 '09 at 19:29