2

好吧,对于一个学校项目,我卑鄙的组长让我做一个“回调”类来存储一个函数,不管它的签名是什么,最后这个类必须存放在一个容器中。

答案是从 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;
  };

因此,任何没有这种丑陋方式和功能齐全的想法都将不胜感激。

总结一下:我只需要通过一个指向基类的指针来调用派生类中存储的函数,但据我所知,由于静态模板和运行时多态性之间的相反,这是不可能的。

4

0 回答 0