2011-12-05 11 views
1

標準的な静的コールバック関数でうまく動作するpthreadsに基づく単純なスレッドクラスがあります。C++の一般化11ラムダで動作するスレッドクラス

スレッドをlambdaでも使用できるように一般化することはできますか?

問題:

  • sandbox.cpp:26:27エラー:タイプから無効なキャストの主要(INT、CHAR * ):: ' 'のボイド' と入力する

  • thread_cb()は、一般的に呼び出し可能なものに戻ってvoid*をキャストに対処する必要が

私は2番目の問題は、テンプレートメソッドや多分std :: functionで解決されるかもしれないと思っています。

#include <vector> 
#include <iostream> 

#include <pthread.h> 

class Threads 
{ 
    public: 
     Threads() { } 
     ~Threads() { } 

    private: 
     static void *thread_cb(void *v) 
     { 
      // following will also need to change 
      void (*my_fptr)() = 
       reinterpret_cast<void(*)()>(reinterpret_cast<long long>(v)); 
      my_fptr(); 
      return nullptr; 
     } 

    public: 
     template<typename CALLBACK> 
     void spawn(CALLBACK cb) 
     { 
      pthread_t t; 
      void *p = (void*)(cb); // problem here 
      pthread_create(&t, nullptr, thread_cb, p); 
      m_threads.push_back(t); 
     } 

     void join_all() 
     { 
      for (auto& p : m_threads) 
       pthread_join(p, nullptr); 
     } 

    private: 
     std::vector<pthread_t> m_threads; 
}; 

static void my_cb() 
{ 
    std::cerr << "bar" << std::endl; 
} 

int main(int argc, char** argv) 
{ 
    Threads t; 

    t.spawn(my_cb); // ok 
    t.spawn([]() { std::cerr << "foo" << std::endl; }); // not ok 

    t.join_all(); 

    return 0; 
} 
+2

あなたは既にC++ 11の土地にいるので(あなたがラムダについて話しているように)、 'std :: thread'を使うことはできません。 –

+2

C++ 11を使用している場合は、なぜpthreadsに気をつけますか?ちょうどstd :: threadを使用してください。ラムダや呼び出し可能なものを直接使用することができます。 – bames53

+0

特別な理由はありません(従来のコードからの移行) - std :: threadへの移行勧告のために - 私はstd :: threadに再コードします – kfmfe04

答えて

1

「ラムダから関数へのポインタ」変換を使用できます。 ...可能であれば、std::threadを強くお勧めします。

template<typename CALLBACK> 
void spawn(CALLBACK cb) 
{ 
    pthread_t t; 
    // void *p = (void*)(cb); 
    // pthread_create(&t, nullptr, thread_cb, p); 
    void (*pfn)() = cb; // function pointer to `void()` 
    pthread_create(&t, nullptr, thread_cb, reinterpret_cast<void*>(pfn)); 
    m_threads.push_back(t); 
} 
関連する問題