使用std::async启动类成员函数的模板函数

template function to launch a class member function with std::async

本文关键字:函数 成员 std async 启动 使用      更新时间:2023-10-16

我想写一个模板函数,它可以接受任何类/结构的对象,并在线程中调用其任何成员函数。以下不编译,我猜它不能算出来:std::result_of< F(Args...) >::type .

有什么建议吗?

class test_f {
public:
  int f(int m) {
    std::cout << " call f : " << m << std::endl;
    return 1;
  }
};
template<typename F, typename T, typename... Args>
std::future<typename std::result_of<F(Args...)>::type>
Async(F&& f, T&& t, Args&&... params) {
  return(std::async(std::launch::async, std::forward<F>(f),
      std::forward<T>(t), std::forward<Args>(params)...));
}
int main() {
  test_f tf ;
  auto a = Async(&test_f::f, &tf, 1) ;
}

如果你可以使用c++ 14,就使用auto:

template<typename F, typename T, typename... Args>
auto Async(F&& f, T&& t, Args&&... params) {
  return(std::async(std::launch::async, std::forward<F>(f),
      std::forward<T>(t), std::forward<Args>(params)...));
}

否则你需要这样做:

auto Async(F&& f, T&& t, Args&&... params) 
    -> std::future<decltype( 
         (t->*f) (std::forward<Args>(params)...) )>            
       )> { // .. same as before

你只是错过了一个参数在你的result_of声明。您的函数F需要TArgs...,您忘记了T:

template<typename F, typename T, typename... Args>
std::future<typename std::result_of<F(T, Args...)>::type>
//                                   ^^^^
Async(F&& f, T&& t, Args&&... params) {
  return(std::async(std::launch::async, std::forward<F>(f),
      std::forward<T>(t), std::forward<Args>(params)...));
}

或者,T是完全不必要的,因为您任意地将自己限制为1+参数函数。而且很容易被遗忘。所以你可以删掉它:

template<typename F, typename... Args>
std::future<typename std::result_of<F(Args...)>::type>
Async(F&& f, Args&&... params) {
  return(std::async(std::launch::async, std::forward<F>(f),
      std::forward<Args>(params)...));
}