2011-12-05 26 views
1

我有一個簡單的基於pthreads的線程類,它可以與標準的靜態回調函數一起工作。推廣C++ 11線程類以使用lambda

是否有可能推廣線程來使用lambdas呢?

問題:

  • sandbox.cpp:27:26:錯誤:從類型無效的轉換 '主(INT,字符* )::' 爲類型 '空隙'

  • thread_cb()需要處理一般鑄造void*回東西贖回

我懷疑第二個問題可能用模板方法或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

是否有某些原因,你不能只使用'std :: thread',因爲你已經在C++ 11中(正如你正在談論lambdas)? –

+2

如果你使用C++ 11,爲什麼要麻煩pthreads?只需使用std :: thread。您可以直接使用lambdas或任何可調用的東西。 – bames53

+0

沒有特別的原因(從遺留代碼轉換) - 爲推薦移動到std ::線程的ty - 我將重新編碼爲std :: thread – kfmfe04

回答

1

您可以使用「lambda to function pointer」轉換。 ...因爲它可能,我強烈建議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); 
}