基类中的成员函数包装器

时间:2019-06-18 20:02:05

标签: c++

我正在尝试构建一个抽象类,该类提供一个函数,该函数可以在std :: future内运行任何传递的成员函数,但是我不知道如何编写函数签名。它必须接受基类和子类的任何成员类。我有以下内容:

template<typename T>
class Dao {
    public:
    virtual T Create(T obj) = 0;
    virtual T Upsert(T obj) = 0;
    virtual void Delete(int id) = 0;
    virtual T Get(int id) = 0;

    // This function is supposed to run any member function passed to it
    // inside the future. The passed function can be either from the Dao 
    // class or one of its derived classes.
    template <typename U, typename... Args>
    std::future<U> RunAsync(U (Dao::*func)(Args...), Args... args){
      return std::async(std::launch::async,func,this,args...);
    }
};
class ModelDao : public Dao<Model> {
   public:
   // implementing the virtual functions
   MyModel Foo(){ ... };
};
class Model { ... };

我唯一可以使用它的方法是在Dao类中声明的函数:

std::future<Model> f = dao.RunAsync(&Dao<Model>::Get, 100);

还有其他东西抛出这样的东西:

template argument deduction/substitution failed:
mismatched types 'Dao<Model>' and 'ModelDao' 
'Foo' is not a member of 'Dao<Model>'

但是我想像这样使用它们(如果不能同时使用f1或f3都可以):

ModelDao mDao; 
Model mModel;
std::future<Model> f1 = mDao.RunAsync(&Dao::Create,mModel);
std::future<void> f2 = mDao.RunAsync(&ModelDao::Foo);
std::future<Model> f3 = mDao.RunAsync(&ModelDao::Create,mModel);

我知道我可以这样使用Dao

ModelDao mDao;
std::future<Model> f = std::async(std::launch::async, &ModelDao::Get,&mDao,100);
std::future2<void> f2 = std::async(std::launch::async [&](){mDao.Foo();});

但是我发现第一种方法更容易输入并且可能更易于维护。

1 个答案:

答案 0 :(得分:1)

尝试:

template <typename U, typename Q, typename... Args>
std::future<U> RunAsync(U (Q::*func)(Args...), Args... args){
  return std::async(std::launch::async, func, static_cast<Q*>(this), args...);
}

注意:我没有为Q的后代添加Dao<T>类型的检查。如果您使用虚拟继承,那么static_cast可能还不够,因此您可能不得不使用dynamic_cast