Передача шаблона переменной в pthread_create - PullRequest
0 голосов
/ 23 октября 2018

Я понимаю, что pthread_create принимает аргумент void*(*)(void*) и void*, поэтому я сделал 2 (неудачные) попытки обернуть функцию и аргументы ...:

a.Создание функции void *run(void*) в стиле C, которая будет вызывать переданный ей объект std::function:

class thread
{
public:
    typedef std::function<void()> functor_t;

    static void* run(void* f) 
    {
        functor_t* functor = (functor_t*)f;
        (*functor)();
        delete functor;
        return nullptr;
    }

    template<typename Callable, typename... Args>
    explicit thread(size_t stack_size, Callable && callable, Args&&... args) {
        auto task_ptr = std::make_shared<std::packaged_task<decltype(callable(args...))()>>(
            std::bind(std::forward<Callable>(callable), std::placeholders::_1, std::forward<Args>(args)...)
            );
        functor_t* functor = new functor_t([task_ptr]() {
            (*task_ptr)();
        });

        pthread_attr_t attr = { 0};
        if (pthread_attr_init(&attr) == 0)
        {
            m_joinable = pthread_attr_setstacksize(&attr, stack_size) == 0 &&
                         pthread_create(&m_id, &attr, &run, functor);
            pthread_attr_destroy(&attr);
        }
    }
private:
    pthread_t   m_id        = -1    ;
    bool        m_joinable  = false ;
};

Это приводит к следующей ошибке в GCC 4.8.5:

/ usr / include / c ++ / 4.8.2 / function: в экземпляре 'struct std :: _ Bind_simple (std :: _ Placeholder <1>, int)) (int *)>> ()>': / usr /include / c ++ / 4.8.2 / future: 1284: 55: требуется из 'void std :: __uture_base :: _ Task_state <_Fn, _Alloc, _Res (_Args ...)> :: _ M_run (_Args ...) [с _Fn= std :: _ Bind (std :: _ Placeholder <1>, int)) (int *)>;_Alloc = std :: allocator;_Res = void;_Args = {}] 'thread.cpp: 17: 1: требуется здесь /usr/include/c++/4.8.2/functional:1697:61: ошибка: нет типа с именем' type 'в классе' std :: result_of (std :: _ Placeholder <1>, int)) (int *)>> ()> 'typedef typename result_of <_Callable (_Args ...)> :: type result_type;^ /usr/include/c++/4.8.2/functional:1727:9: ошибка: нет типа с именем 'type' в 'классе std :: result_of (std :: _ Placeholder <1>, int)) (int *)>> ()> '_M_invoke (_Index_tuple <_Indices ...>) ^

b.Следуя этому примеру http://coliru.stacked -crooked.com / a / a6c607514601b013

class thread
{
public:
    template< typename Callable, typename... Args >
    explicit thread(size_t stack_size, Callable&& callable, Args&&... args )
    {
        auto l = new auto([=]{ callable(args...); });
        auto te = [](void* rp) -> void*
        {
            auto p = reinterpret_cast<decltype(l)>(rp);
            (*p)();
            delete p;
            return nullptr;
        };
        pthread_attr_t attr = { 0};
        if (pthread_attr_init(&attr) == 0)
        {
            m_joinable = pthread_attr_setstacksize(&attr, stack_size) == 0 &&
                         pthread_create(&m_id, &attr, te, l);
            pthread_attr_destroy(&attr);
        }
    }
private:
    pthread_t   m_id        = -1    ;
    bool        m_joinable  = false ;
};

Предполагается, что это работает в clang, но в GCC 4.8.5 не работает с:

В файле, включенном из thread.cpp: 2: 0: thread.h: В лямбда-функции: thread.h: 82: 37: ошибка: пакеты параметров не раскрываются с помощью «...»: auto l = newauto ([=] {callable (args ...);});^ thread.h: 82: 37: примечание:
'args' thread.h: 82: 41: ошибка: шаблон расширения 'args' не содержит пакетов аргументов auto l = new auto ([=] {callable (args...);});^ thread.h: в экземпляре 'struct thread :: thread (size_t, Callable &&, Args && ...) [with Callable = void () (int );Args = {int *};size_t = длинная беззнаковая int] :: __ lambda4 ': thread.h: 82: 48:
требуется от' thread :: thread (size_t, Callable &&, Args && ...) [with Callable = void () (INT );Args = {int *};size_t = long unsigned int] 'thread.cpp: 14: 32: требуется отсюда thread.h: 82: 37: ошибка: использование недопустимого поля' thread :: thread (size_t, Callable &&, Args && ...) :: __ lambda4:: __ args 'auto l = new auto ([=] {callable (args ...);});^ thread.h: 83: сбит с толку из-за более ранних ошибок, спасаясь

Оба выполнялись с следующей основной:

int g=5;

void run(int *i)
{
    printf("t\n");
}

int main()
{

    gs_thread t(256*1024, &run, &g);
    printf("m\n");
    t.join();
}

1 Ответ

0 голосов
/ 23 октября 2018

Если вы удаляете std::placeholders::_1, из первой версии, он компилируется с gcc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...