2016-11-11 5 views
0

C++でスレッドプールを作成しようとしています。概念は、mainは新しいTaskを作成し、ThreadPoolクラスはTaskオブジェクトを取得し、他の作業を実装するということです。これは、Taskクラスです:戻り値と変数テンプレートのバインド

私はそれを使用しようとしていますか
template<typename ... Arguments> 
     class Task{ 
      // 
     public: 
      Task(std::function<void (Arguments...)> _func, Arguments... _args){ 
       auto f1 = std::bind(_func, _args...); 
       f1(); 
      }; 
      void run(){ 

      }; 
     }; 

と、この:

#include <iostream> 
#include <algorithm> 

#include "Task.hpp" 

void prtinhi(int a) 
{ 
    std::cout << a << std::endl; 
    return; 
} 

int main(){ 

    Task<int> task(prtinhi, 5); 
    task.run(); 
    return 0; 
} 

が明らかTaskオブジェクトは、ThreadPoolのに渡され、ThreadPoolのは、(実行を呼び出します)に従っていくつかの論理。 このコードは、print 5を正常に実行します。しかし、私が望むのは、f1()をrun()関数から呼び出すことです。私はクラスのメンバとしてauto f1定義のそれぞれで独立し持っているTaskクラスを変更する場合、私はエラーを取得:

non-static data member declared ‘auto’ 

私はそれが静的宣言した場合、私はそれに値を割り当てることはできません。 どうすればこの問題を解決できますか?それを行うより良い方法はありますか?

+0

おそらく 'decltype'ですか? – DavidW

+0

私はここでdecltypeが私を助けることができません... –

答えて

2

なぜタスクは関数の引数について知る必要がありますか?タスクは、タイプ消去された呼び出し可能オブジェクトvoid()でなければなりません。

戻り値を取得する必要がある場合は、std::futureが必要です。次のように

ThreadPoolを実装することができます。

struct ThreadPool 
{ 
    some_lockfree_queue<Task> _queue; 
    std::vector<std::thread> _workers; 

    void initialize() 
    { 
     for(int i = 0; i < num_threads; ++i) 
     { 
      _workers.emplace_back([this] 
      { 
       Task t = _queue.try_dequeue(); 
       t(); 
      }); 
     } 
    } 
}; 

std::bind悪いある(詳細はthis talk by STLを見て)。必要な引数をバインドしてnullary関数を返すには、lambdasを使用する必要があります。

+0

正確な時間をtalk re:バインドの問題にリンク:https://youtu.be/zt7ThwVfap0?t=1721 – Shillard

関連する問題