将非静态函数绑定到回调时出现问题

Issue with binding non static function to callback

本文关键字:问题 回调 静态函数 绑定      更新时间:2023-10-16

我无法将非静态成员函数绑定到回调。 我必须将test2类成员函数here()绑定到test1成员callBack这是一个std::function,但我找不到这样做的方法。如果你有任何想法,任何人都可以建议我。

在代码中显示

#include <iostream>
#include <stdint.h>
#include <functional>
using namespace std;
class test1{
public:
typedef std::function<void()> callback_function_t;
callback_function_t callBack;
void setCallback(callback_function_t _callBackfn){
callBack = std::move(_callBackfn);
}
void check(void){
callBack();
}
};
class test2{
public:
void here(){
cout << "safsafsdf" << endl;
}
};
int main(){
test1 t1;
test2 t2;
t1.setCallback(t2.here); // Can't Works
return 0;
}

必须在 test1 回调中设置。

问题是,在创建std::function时,您还必须提供必须调用成员函数的类的实例。另一个答案使用std::bind,这是一个可能的解决方案。 为了提高可读性,我建议使用 lambda 函数作为替代方案:

t1.setCallback([&t2](){t2.here();}); 

请注意,此处捕获t2作为引用,因此必须确保t1使用回调时t2处于活动状态。

或者,您可以按值捕获(制作副本(

t1.setCallback([t2]() mutable {t2.here();}); 

并且您需要mutable关键字来允许调用非 const 限定成员函数

最后,您还可以在 lambda 内移动t2,避免复制

t1.setCallback([t2 = std::move(t2)]() mutable {t2.here();}); 

这是通用捕获,可从 C++14 开始提供。在您的特定示例中,使用std::move几乎不会产生任何区别,但一般来说,如果对象很复杂,这可能会有用。

用于将this指针绑定到t1的语法不正确。你不能简单地编写t2.here来获得一个函数,当调用时,它本质上与t2.here()相同。

一种可能的解决方案是通过std::bind()绑定this对象,例如

t1.setCallback(std::bind(&test2::here, t2));

但请记住,这会在最终存储在t2.callBack中的函数对象内创建t2的副本。对t2的修改不会影响t1.callBack。如果您确定t1总是比t2寿命长,您还可以创建引用

t1.setCallback(std::bind(&test2::here, std::ref(t2)));