尝试从模板类分配回调函数时出现以下错误。我正在访问对象上的回调函数和回调赋值函数。我无法创建回调函数
static
,因为它需要访问指向 Buffer 对象的非静态指针。我怎样才能做到这一点?
下面是代码。这可以在 https://www.onlinegdb.com/
上执行main.cpp: In function ‘int main()’:
main.cpp:62:37: error: invalid use of non-static member function ‘void Class1::Callback() [with T = unsigned char]’
62 | pBuffer->SetWrCallback(pClass1->Callback);
| ~~~~~~~~~^~~~~~~~
main.cpp:43:10: note: declared here
43 | void Callback()
| ^~~~~~~~
#include <iostream>
using namespace std;
using CallbackAfterWrite = void (*)(void);
template<typename T>
class Buffer
{
public:
Buffer() {}
~Buffer() {}
std::size_t size()
{
return 10;
}
void SetWrCallback(CallbackAfterWrite wrCallback)
{
mWrCallback = wrCallback;
}
private:
CallbackAfterWrite mWrCallback;
};
template<typename T>
class Class1
{
public:
Class1() {}
~Class1() {}
void Callback()
{
if(0 != mpBuffer->size())
{
std::cout<< "Trigger callback" <<endl;
}
}
private:
Buffer<T> *mpBuffer;
};
int main()
{
cout<<"Hello World"<<endl;
Buffer<uint8_t>* pBuffer = new Buffer<uint8_t>;
Class1<uint8_t>* pClass1 = new Class1<uint8_t>;
pBuffer->SetWrCallback(pClass1->Callback);
return 0;
}
如果回调函数是
static
并且不需要访问非静态私有数据成员,则此方法有效,但不幸的是,我无法摆脱它。
试试这个:
#include <iostream>
#include <functional>
using namespace std;
template<typename T>
class Buffer
{
public:
Buffer() {}
~Buffer() {}
std::size_t size()
{
return 10;
}
void SetWrCallback(std::function<void()> wrCallback)
{
mWrCallback = wrCallback;
}
private:
std::function<void()> mWrCallback;
};
template<typename T>
class Class1
{
public:
Class1(Buffer<T>* pBuffer) : mpBuffer(pBuffer) {}
~Class1() {}
void Callback()
{
if (0 != mpBuffer->size())
{
std::cout << "Trigger callback" << endl;
}
}
private:
Buffer<T>* mpBuffer;
};
int main()
{
cout << "Hello World" << endl;
Buffer<uint8_t>* pBuffer = new Buffer<uint8_t>;
Class1<uint8_t>* pClass1 = new Class1<uint8_t>(pBuffer);
pBuffer->SetWrCallback([pClass1]() { pClass1->Callback(); });
return 0;
}
出现您遇到的问题是因为您尝试将非静态成员函数分配为函数指针的回调。非静态成员函数有一个隐式的“this”参数,该参数指向类的实例。然而,函数指针默认不捕获“this”指针。
要解决这个问题,您可以使用 lambda 和 std::function 的组合。 Lambda 可以捕获类的实例,然后您可以将 lambda 包装在 std::function 中,该函数可以分配给回调。
在 Buffer 类中,我将 mWrCallback 的类型更改为 std::function