Обобщающий класс C ++ 11 Threads для работы с лямбдами - PullRequest
1 голос
/ 05 декабря 2011

У меня есть простой класс Threads, основанный на pthreads, который отлично работает со стандартной статической функцией обратного вызова.

Можно ли обобщить Threads и для работы с лямбдами?

проблемы:

  • sandbox.cpp: 27: 26: ошибка: недопустимое приведение типа 'main (int, char *) ::' to type 'void '

  • 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;
}

1 Ответ

1 голос
/ 24 июня 2013

Вы можете использовать преобразование «лямбда в указатель функции». ... как бы то ни было, я настоятельно рекомендую 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 );
}
...