具有动态回调函数类型的 C++ 模板 class
C++ template class with dynamic callback function type
在下面的代码中,我希望用户能够创建具有特定类型的消费者 class,例如 Consumer<StateA>
,以便他们的回调函数可以正确处理他们提供的类型。但是在下面的代码中,编译器会报错,因为在编译时,不会生成对 StateB
consume 方法中的函数的调用。 consume 方法来自基础 class,它们必须被覆盖。
template <class T>
class Consumer : ConsumerBase
{
public:
Consumer(std::function<void(T&)> _callback){
callback = _callback;
}
virtual void consume(StateA& state) {
callback(state);
}
virtual void consume(StateB& state) {
callback(state);
}
private:
std::function<void(T&)> callback;
};
基础Class:
class ConsumerBase
{
public:
virtual void consume(StateA& state) = 0;
virtual void consume(StateB& state) = 0;
};
我怎样才能完成这项工作?
The consume methods come from a base class and they have to be overriden. [...] How can I make this work?
我想一个可能的解决方案是开发几个 consume_h()
("consume helper") 方法。
第一个完全匹配T
(class的模板类型)调用回调函数
void consume_h (T & state)
{ callback(state); }
第二个是什么都不做的模板版本
template <typename U>
void consume_h (U &)
{ }
现在你可以覆盖两个虚方法调用consume_h()
virtual void consume (StateA & state)
{ consume_h(state); }
virtual void consume (StateB & state)
{ consume_h(state); }
这样T
对应的虚方法,调用调用回调的consume_h()
;另一个调用什么都不做的模板consume_h()
。
下面是一个完整的编译示例
#include <functional>
struct StateA { };
struct StateB { };
struct ConsumerBase
{
virtual void consume (StateA &) = 0;
virtual void consume (StateB &) = 0;
};
template <typename T>
class Consumer : ConsumerBase
{
public:
Consumer (std::function<void(T&)> cb0) : callback{cb0}
{ }
void consume_h (T & state)
{ callback(state); }
template <typename U>
void consume_h (U &)
{ }
virtual void consume (StateA & state)
{ consume_h(state); }
virtual void consume (StateB & state)
{ consume_h(state); }
private:
std::function<void(T&)> callback;
};
int main()
{
Consumer<StateA> csa{[](StateA &){ std::cout << "A" << std::endl; }};
Consumer<StateB> csb{[](StateB &){ std::cout << "B" << std::endl; }};
StateA sa;
StateB sb;
csa.consume(sa); // print A
csb.consume(sb); // print B
}
在下面的代码中,我希望用户能够创建具有特定类型的消费者 class,例如 Consumer<StateA>
,以便他们的回调函数可以正确处理他们提供的类型。但是在下面的代码中,编译器会报错,因为在编译时,不会生成对 StateB
consume 方法中的函数的调用。 consume 方法来自基础 class,它们必须被覆盖。
template <class T>
class Consumer : ConsumerBase
{
public:
Consumer(std::function<void(T&)> _callback){
callback = _callback;
}
virtual void consume(StateA& state) {
callback(state);
}
virtual void consume(StateB& state) {
callback(state);
}
private:
std::function<void(T&)> callback;
};
基础Class:
class ConsumerBase
{
public:
virtual void consume(StateA& state) = 0;
virtual void consume(StateB& state) = 0;
};
我怎样才能完成这项工作?
The consume methods come from a base class and they have to be overriden. [...] How can I make this work?
我想一个可能的解决方案是开发几个 consume_h()
("consume helper") 方法。
第一个完全匹配T
(class的模板类型)调用回调函数
void consume_h (T & state)
{ callback(state); }
第二个是什么都不做的模板版本
template <typename U>
void consume_h (U &)
{ }
现在你可以覆盖两个虚方法调用consume_h()
virtual void consume (StateA & state)
{ consume_h(state); }
virtual void consume (StateB & state)
{ consume_h(state); }
这样T
对应的虚方法,调用调用回调的consume_h()
;另一个调用什么都不做的模板consume_h()
。
下面是一个完整的编译示例
#include <functional>
struct StateA { };
struct StateB { };
struct ConsumerBase
{
virtual void consume (StateA &) = 0;
virtual void consume (StateB &) = 0;
};
template <typename T>
class Consumer : ConsumerBase
{
public:
Consumer (std::function<void(T&)> cb0) : callback{cb0}
{ }
void consume_h (T & state)
{ callback(state); }
template <typename U>
void consume_h (U &)
{ }
virtual void consume (StateA & state)
{ consume_h(state); }
virtual void consume (StateB & state)
{ consume_h(state); }
private:
std::function<void(T&)> callback;
};
int main()
{
Consumer<StateA> csa{[](StateA &){ std::cout << "A" << std::endl; }};
Consumer<StateB> csb{[](StateB &){ std::cout << "B" << std::endl; }};
StateA sa;
StateB sb;
csa.consume(sa); // print A
csb.consume(sb); // print B
}