Generalizing C++11 Threads class to work with lamb

2019-08-02 20:59发布

I have a simple Threads class based on pthreads which works fine with a standard static callback function.

Is it possible to generalize Threads to work with lambdas, too?

problems:

  • sandbox.cpp:27:26: error: invalid cast from type ‘main(int, char*)::’ to type ‘void

  • thread_cb() needs to deal with generically casting void* back into something callable

I suspect the second problem may be solved with template methods or maybe std::function, but not sure how.

#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条回答
Summer. ? 凉城
2楼-- · 2019-08-02 21:54

You can use "lambda to function pointer" conversion. ...be that as it may, I strongly recommend 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 );
}
查看更多
登录 后发表回答