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 шт):
Например можно упаковать аргументы в кортеж, передать указатель на этот кортеж, а потом в функции 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;
}
Я бы вот как сделал.
Делаете лямбду без параметров, которая захватывает все необходимое и вызывает нужную функцию:
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 - адрес первой лямбды.
Домашнее задание - придумать, как прикрутить ко всему этому возвращение значения из потока.