在 C++ class 模板中要求 Callable 是静态的
Callable being required to be static in C++ class template
我想在程序中进行以下 class 设置:
- 一个实现缓冲区的class。此缓冲区在满时会生成一个线程,该线程进行回调以处理如何处理已满缓冲区。
- 包含缓冲区对象的基本 class 模板。实现回调函数,调用派生 class.
中定义的虚函数
- 从基础 class 继承并实现数据处理的派生 class。
首先,最小的可复制示例:
#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 是静态的,但如果我那样做,那么我将无法访问对象的成员。有没有办法对此进行排序,或者只是一个糟糕的想法?
您正在传递 class 成员函数,因此您需要在 CallbackBuffer
class 中包含类似以下内容的内容:
void (Base<T>::*callback)(std::vector<T>);
// ...
void setCallback(void (Base<T>::*cb)(std::vector<T>)) {
callback = cb;
}
并在 Base
class:
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); });
}
恕我直言,这比传递成员指针更具可读性和灵活性
我想在程序中进行以下 class 设置:
- 一个实现缓冲区的class。此缓冲区在满时会生成一个线程,该线程进行回调以处理如何处理已满缓冲区。
- 包含缓冲区对象的基本 class 模板。实现回调函数,调用派生 class. 中定义的虚函数
- 从基础 class 继承并实现数据处理的派生 class。
首先,最小的可复制示例:
#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 是静态的,但如果我那样做,那么我将无法访问对象的成员。有没有办法对此进行排序,或者只是一个糟糕的想法?
您正在传递 class 成员函数,因此您需要在 CallbackBuffer
class 中包含类似以下内容的内容:
void (Base<T>::*callback)(std::vector<T>);
// ...
void setCallback(void (Base<T>::*cb)(std::vector<T>)) {
callback = cb;
}
并在 Base
class:
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); });
}
恕我直言,这比传递成员指针更具可读性和灵活性