好吧,对于一个学校项目,我卑鄙的组长让我做一个“回调”类来存储一个函数,不管它的签名是什么,最后这个类必须存放在一个容器中。
答案是从 Base 类中创建一个 Derived 模板类,这样我们就可以存储它。问题出在实际函数的执行上,因为它需要可变数量和类型的参数,我不能使用多态性来执行它。
我通过使用动态转换和一些模板参数(参见下面的代码)来尝试检索类型来避免这个问题。虽然它在大多数情况下确实有效,但它会导致某些签名出现大问题(例如,如果函数在参数中采用“void *”)。代码会更健谈......我将它简化了一点以更快,它实际上也需要指向成员的指针。
#include <functional>
template <typename R, typename... Arguments>
class CallBack;
class ACallBack
{
protected:
ACallBack()
{
}
public:
virtual ~ACallBack()
{
}
template <typename R, typename... Arguments>
R run(Arguments &&... args)
{
CallBack<R, Arguments...> *C;
// Here is the problem i would like to avoid, and do it properly if possible
if ((C = dynamic_cast<CallBack<R, Arguments...> *>(this)))
{
return (*C)(std::forward<Arguments>(args)...);
}
return (R());
}
template <typename... Arguments>
void operator()(Arguments &&... args)
{
run<void>(std::forward<Arguments>(args)...);
}
template <typename R, typename... Args>
static CallBack<R, Args...>* generate(R(*f)(Args...))
{
return new CallBack<R, Args...>(f);
}
};
对于实际的派生类:
template <typename R, typename... Arguments>
class CallBack : public ACallBack
{
public:
template <typename F>
CallBack(F&& f) : _fct(std::forward<F>(f))
{
}
virtual ~CallBack()
{
}
R operator()(Arguments &&... args)
{
return (_fct(std::forward<Arguments>(args)...));
}
private:
std::function<R(Arguments...)> _fct;
};
因此,任何没有这种丑陋方式和功能齐全的想法都将不胜感激。
总结一下:我只需要通过一个指向基类的指针来调用派生类中存储的函数,但据我所知,由于静态模板和运行时多态性之间的相反,这是不可能的。