This:
auto tuple = std::forward_as_tuple(args...);
Создает кортеж ссылок на args...
Это и есть работа forward_as_tuple
. Затем вы захватываете этот набор ссылок по значению:
m_thread = new std::thread([=]{ /* ... */ });
Так что, как только ваши аргументы go выходят за рамки, вы только держитесь за ссылки на них ... и это будет зависать.
Но на самом деле вам ... вообще не нужен кортеж. Просто скопируйте сами аргументы:
m_thread = std::thread([=]() {
func(args...); // func and args, no tuple here
});
Также не пишите new thread
- thread
- это уже тип дескриптора, просто создайте его.
Выше копирует аргументы. Если вы хотите переместить их, то в C ++ 17, да, вам нужно иметь tuple
и использовать std::apply
. Но не forward_as_tuple
... просто make_tuple
:
m_thread = std::thread([func, args=std::make_tuple(std::move(args)...)]() mutable {
std::apply(func, std::move(args));
});
В C ++ 20 вам больше не понадобится tuple
, и вы можете написать расширение пакета:
m_thread = std::thread([func, ...args=std::move(args)]() mutable {
func(std::move(args)...);
});