шаблонная функция для запуска функции-члена класса с помощью std::async

#c #c 11

#c #c 11

Вопрос:

Я хотел бы написать шаблонную функцию, которая может принимать объект любого класса / структуры и вызывать любую его функцию-член в потоке. Следующее не компилируется, я думаю, это не может понять : 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(Famp;amp; f, Tamp;amp; t, Argsamp;amp;... 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(amp;test_f::f, amp;tf, 1) ;
}
  

Комментарии:

1. Если бы вы могли использовать decltpe и реплицировать тело функции в сигнатуре функции.

2. Вы не забыли передать T в result_of ?

Ответ №1:

Если вы можете использовать C 14, просто используйте auto :

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

В противном случае вам нужно что-то вроде этого:

 auto Async(Famp;amp; f, Tamp;amp; t, Argsamp;amp;... params) 
    -> std::future<decltype( 
         (t->*f) (std::forward<Args>(params)...) )>            
       )> { // .. same as before
  

Ответ №2:

Вам просто не хватает аргумента в вашем result_of объявлении. Ваша функция F принимает T и Args... , и вы забыли T :

 template<typename F, typename T, typename... Args>
std::future<typename std::result_of<F(T, Args...)>::type>
//                                   ^^^^
Async(Famp;amp; f, Tamp;amp; t, Argsamp;amp;... 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(Famp;amp; f, Argsamp;amp;... params) {
  return(std::async(std::launch::async, std::forward<F>(f),
      std::forward<Args>(params)...));
}