C++ 函子和零

发布于 2024-07-27 18:52:09 字数 2277 浏览 13 评论 0原文

首先是免责声明,我将替换一堆使用 boost::function 和 boost::bind 的代码。 但是,我正在转向不允许 rtti 的代码库。 我想继续使用 boost,但不知道是否有办法绕过这个限制。

因此,我试图模仿它的一些功能,但要简化得多。 我有一个回调类:

   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;
};

这允许我用零参数执行简单的回调:

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();
}

我希望能够将我的回调对象分配为零作为默认参数,如下所示:

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;
};

这在使用 boost::function 时有效,就像你可以做的那样:

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;
};

我想象一下 boost 在这里发挥了一些魔力。 我知道我可以将参数更改为指针而不是引用,但正如我所说,我正在替换大量代码,并且希望最大限度地减少 boost 更改的影响。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

琉璃繁缕 2024-08-03 18:52:10

Boost 并没有什么神奇的作用。 0 只是函数指针构造函数的 NULL 函数指针。

我建议在你的情况下你只提供一个默认的构造函数

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

并使 doSomething 看起来像

void doSomething(const Callback0<Wtf, void>& callback = Callback0<Wtf, void>()) {

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>()) {
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文