variadict template параметр из указателя c++

Имеется шаблонный класс POSIX-потоков

template<class Res, class ...Args>
class MyPThread
{
  public:
  Res foo(Args... args){//...
  return Res(); 
               } 

и имеется "первичная"-функция принимающая указатель (именно она и будет передана в pthread_create())

static void* bar(void* arg){
//call foo()
     }
};

как в функции bar() можно достать из указателя параметры и передать их в метод foo()?


Ответы (2 шт):

Автор решения: user7860670

Например можно упаковать аргументы в кортеж, передать указатель на этот кортеж, а потом в функции bar вызвать foo передав этот кортеж посредством std::apply

static void * bar(void * const p_args) noexcept
{
    auto const & args{*static_cast< ::std::tuple< MyPThread *, Args... > * >(p_args)};
    auto res{::std::apply(&MyPThread::foo, args)};
    return nullptr;
}
→ Ссылка
Автор решения: HolyBlackCat

Я бы вот как сделал.

Делаете лямбду без параметров, которая захватывает все необходимое и вызывает нужную функцию:

auto lambda = [...]{...};

Сохраняете ее куда-нибудь, чтобы она не удалилась, пока поток работает.

Делаете еще одну лямбду, без списка захвата, которую будете передавать в pthread_create. Эту лямбду можно никуда не сохранять, после вызова pthread_create она не нужна.

auto invoker = [](void *ptr) -> void*
{
    auto &lambda_ref = *(decltype(lambda) *)ptr;
    lambda_ref();
    return nullptr;
};

Все, теперь в pthread_create в качетсве функции передаете лямбду invoker, а в качестве void *arg - адрес первой лямбды.

Домашнее задание - придумать, как прикрутить ко всему этому возвращение значения из потока.

→ Ссылка