【问题标题】:How to set a callback by binding a class method in C++如何通过在 C++ 中绑定类方法来设置回调
【发布时间】:2022-01-17 09:12:15
【问题描述】:

我有两个不同的课程AB

B 包含对A 实例的引用,但反之则不然。

我需要将B 中包含的std::function<void()>A 类中声明的方法绑定。

代码如下:

class A{
private:
    int id;
public:
    A(int id) : id(id){};
    void display_id(){ std::cout << "id:" << id << std::endl; }
};

class B{
private:
    A *a;
    std::function<void()> f;
public:
    B(A *a): a(a){}
    void set_callback(){
        f = std::bind(a->display_id,this);
    }
    void invoke_callback(){
        f();
    }
};

int main(){
    A a{5};
    B b{&a};
    b.set_callback();
    b.invoke_callback(); //output should be: id 5

    return 0;
}

但是我收到了这个错误:

 error: invalid use of non-static member function 'void A::display_id()'
   19 |     f = std::bind(a->display_id,this);

按照答案中的建议,我通过用 lambda 函数替换 std::bind 解决了这个问题。

void B::set_callback(){
f = std::function<void()>([this](){
    this->a->display_id();
});
}

但我的问题是:std::bind 对应的语法是什么?

【问题讨论】:

  • 您是否尝试将A::display_id 绑定到a?还是this?我怀疑你的意思是std::bind( &amp;A::display_id, a );
  • 由于您在使用std::bind 时遇到困难,我应该补充一点,从 C++14 开始,实际上没有理由使用 std::bind 而不是使用 lambda。人们往往更容易使用 lambda 语法。
  • 你的意思是 f = std::bind( &A::display_id, a ); 或者只是 std::bind( &A::display_id, a ); ?出于我的目的,通过调用 b.invoke_callback() 我应该在 A 的 display_id 的控制台输出上显示。
  • 你永远不会调用set_callback() 所以f 不包含函数。调用它会使程序抛出一个bad_function_call 异常
  • 这只是所有代码的摘录,所以我想念它,但我仍然遇到同样的问题。我正在更新第一篇文章

标签: c++ class stdbind


【解决方案1】:

对于初学者来说,你根本没有打电话给set_callback()

其次,您没有正确调用std::bind()。它需要看起来更像这样:

class B{
private:
    A *a;
    std::function<void()> f;
public:
    B(A *a): a(a){}
    void set_callback(){
        f = std::bind(&A::display_id, a);
    }
    void invoke_callback(){
        f();
    }
};

int main(){
    A a{5};
    B b{&a};
    b.set_callback();
    b.invoke_callback();

    return 0;
}

Online Demo

或者,您可以(并且应该)使用lambda 而不是std::bind()

class B{
private:
    A *a;
    std::function<void()> f;
public:
    B(A *a): a(a){}
    void set_callback(){
        f = [this](){ a->display_id(); };
    }
    void invoke_callback(){
        f();
    }
};

Online Demo

【讨论】:

    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 2014-07-11
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多