C++ 基类中的成员函数包装器

C++ 基类中的成员函数包装器,c++,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

我试图构建一个抽象类,它提供一个函数,在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 { ... };
模板
类刀{
公众:
虚拟T创建(T对象)=0;
虚拟T向上插入(T obj)=0;
虚空删除(int id)=0;
虚拟T Get(int id)=0;
//此函数应该运行传递给它的任何成员函数
//传递的函数可以是来自Dao的
//类或其派生类之一。
样板
std::future RunAsync(U(Dao::*func)(Args…,Args…){
返回std::async(std::launch::async、func、this、args…);
}
};
类ModelDao:公共Dao{
公众:
//实现虚拟功能
MyModel Foo(){…};
};
类模型{…};
我唯一可以使用它的方法是使用Dao类中声明的函数:

std::future<Model> f = dao.RunAsync(&Dao<Model>::Get, 100);
std::future f=dao.RunAsync(&dao::Get,100);
其他任何东西都会抛出这样的东西:

template argument deduction/substitution failed:
mismatched types 'Dao<Model>' and 'ModelDao' 
'Foo' is not a member of 'Dao<Model>'
模板参数推导/替换失败:
不匹配的类型“Dao”和“ModelDao”
“Foo”不是“Dao”的成员
但是我想这样使用它们(如果两者都不可能,f1或f3都可以):

modeldaomdao;
模型模型;
std::future f1=mDao.RunAsync(&Dao::Create,mModel);
std::future f2=mDao.RunAsync(&ModelDao::Foo);
std::future f3=mDao.RunAsync(&ModelDao::Create,mModel);
我知道我可以像这样使用这把刀

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();});
modeldaomdao;
std::future f=std::async(std::launch::async,&ModelDao::Get,&mDao,100);
std::future2 f2=std::async(std::launch::async[&](){mDao.Foo();});
但我发现第一种方法更容易输入,而且可能更容易维护。

试试:

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...);
}
模板
std::future RunAsync(U(Q::*func)(Args…,Args…){
返回std::async(std::launch::async、func、static\u cast(this)、args…);
}
注意:我没有添加检查
Q
类型是否是
Dao
的后代。如果您使用虚拟继承,那么
static\u cast
可能不够,您可能会被迫使用
dynamic\u cast

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...);
}