我希望在程序中设置以下类:
- 一个实现缓冲区的类。这个缓冲区在满的时候会产生一个线程,这个线程会进行回调来处理如何处理满的缓冲区
- 包含缓冲区对象的基类模板。实现回调函数,该函数对派生类中定义的虚拟函数进行调用
- 从基类继承并实现如何处理数据的派生类
首先,可重复性最小的示例:
#include <vector>
#include <iostream>
#include <thread>
template <typename T>
class CallbackBuffer
{
public:
std::vector<T> buffer;
void (*callback)(std::vector<T>);
std::thread writerThread;
CallbackBuffer(int bufferSize = 10)
{
buffer.resize(bufferSize);
}
void setCallback(void (*cb)(std::vector<T>))
{
callback = cb;
}
void writeCall()
{
writerThread = std::thread(callback, buffer);
}
};
template <typename T>
class Base
{
public:
CallbackBuffer<T> buffer;
Base()
{
buffer.setCallback(bufferHandler);
}
void bufferHandler(std::vector<T> v)
{
for(auto &i : v)
{
write(i);
}
}
virtual void write(T i) = 0;
};
class Derived : public Base<int>
{
public:
Derived()
{
}
void write(int i)
{
std::cout << i << std::endl;
}
};
int main()
{
Derived d;
return 0;
}
我得到以下编译器错误:
error: invalid use of non-static member function ‘void Base<T>::bufferHandler(std::vector<T>) [with T = int]’
因此编译器需要bufferHandler是静态的,但如果我这样做了,那么我就无法访问对象的成员。有没有办法解决这个问题,或者只是一个可怕的想法?
您正在传递类成员函数,因此您需要在CallbackBuffer
类中包含以下内容:
void (Base<T>::*callback)(std::vector<T>);
// ...
void setCallback(void (Base<T>::*cb)(std::vector<T>)) {
callback = cb;
}
在Base
类中:
Base() {
buffer.setCallback(&Base<T>::bufferHandler);
}
演示
成员函数指针的类型与常规函数不同,这就是代码无法工作的原因。您可能想要使用std::function
而不是原始指针:
#include <functional>
//...
std::function<void(std::vector<T>)> callback;
// ...
void setCallback(const std::function<void(std::vector<T>)>& cb) {
callback = cb;
}
然后像这样传递:
Base() {
buffer.setCallback([this](auto& vec){ this->bufferHandler(vec); });
}
IMHO这比传递成员指针更具可读性和灵活性