【问题标题】:Binding a class method to a method of another class将一个类方法绑定到另一个类的方法
【发布时间】:2021-12-14 21:31:01
【问题描述】:

我有两个类,一个是逻辑类,一个是模型类。初始化两者后,我想将b.funB()绑定到a.funA(),其中A a; B b;

class A{
   public:
     bool funA() { doStuff(); }
}


class B{
   public:
     bool funB();
    
    Template<class T>
    void bindBtoA((bool (B::*fun2)(), bool (T::*fun1)(), T *t){
       funB=std::bind( ?);
       // (fun1, t), (&T::fun1, &t), (T::fun1, t), ... ?
    }
}

如何正确绑定这些并摆脱“无法转换”错误(我在实际代码中确实使用了 typedef)

使用 lambda 的答案是可以接受的。但是,funB 必须是可调用的,因为另一个引擎需要获取此 (提示:Q_INVOKABLE),因此将 std::function 用于 A::funA 可能不适用于我的情况。

【问题讨论】:

  • 不清楚你的问题中是否有错别字,所有这些都提到了 fun1、fun2、funA、funB。 例如不存在您的第一段所暗示的A::fun1B::fun1。请提供一个示例,说明您希望如何调用它以及您想要的结果行为。
  • 我认为您使用的词不正确。您不会将两个函数绑定在一起,而是将参数绑定到一个函数。你试图做的事情非常不清楚,但不管它是什么,绑定它都不是。如果我不得不猜测,我会说bindBtoA 应该被称为setCallbackfunB 应该被称为invokeCallback
  • 感谢您的提醒,@paddy 显然,我一直使用函数的参数名称

标签: c++ lambda stdbind


【解决方案1】:

您可以通过 std::function 的魔法来实现这一点,它会隐藏在类 B 中,并对要调用的函数进行类型擦除,从而为您提供所需的通用性。

这是一个完整的例子:

#include <iostream>
#include <functional>

class A
{
public:
    bool funA () { std::cout << "funA\n"; return true; }
};

class B
{
public:
    bool funB ()
    {
        return f ();
    }
    
    template <class T>
    void bindBtoA (bool (T::*fun1) (), T *t)
    {
         f = [t, fun1] { return (t->*fun1) (); };
    }

private:    
    std::function <bool ()> f;
};

int main()
{
    A a;
    B b;
    b.bindBtoA <A> (&A::funA, &a);
    std::cout << b.funB ();
}

Live demo

我认为这适用于 Q_INVOKABLE,但我实际上对此一无所知,因此您必须尝试一下。但如果它确实有效,这是一个很好的方法。

注意:使用发布的代码,只要b 还活着,您就有责任保持a 活着。如果你不能保证,更好的选择是使用std::shared_ptr。或者复制 abindBtoA 中,如果这对你来说是一个实用的解决方案(我猜它不是)。

【讨论】:

  • 很好,但感觉在bindBtoA 中引用t 会更安全。也许:void bindBtoA(bool (T::*fun1)(), T&amp; t) { f = [fun1,&amp;t] { return (t.*fun1)(); }; }
  • @TedLyngmo 有什么不同吗?悬空指针,悬空引用,同样的事情。使用std::shared_ptr 会更安全。无论如何,我会在我的答案中添加一个关于t 生命周期的注释。
  • 也许不是。我在考虑要求一个对象的接口并拒绝可能是nullptrT*,但也许这只是给人一种增加安全感的错误感觉。
  • @TedLyngmo 确实如此。但是通过引用传递将是惯用的,是的。我只是选择了 OP 最初发布的内容。
  • 事实上,当我尝试使用 std::function 执行此操作时,我使用了一个包装器
猜你喜欢
  • 2021-09-17
  • 2018-04-20
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
  • 1970-01-01
  • 2019-07-04
相关资源
最近更新 更多