我正在尝试构建一个抽象类,该类提供一个函数,该函数可以在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();});
但是我发现第一种方法更容易输入并且可能更易于维护。
答案 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
。