I don't understand why the thread given a lambda works but the other one does not... I have a template function that uses a class Printer (with mutex protection for std::cout) to print that it is starting to wait. It waits for the duration passed it and then again uses Printer to tell how long it waited. The definition:
template <typename duration>
void waiting(duration dur, Printer& p);
This is how the threads are created:
std::thread ms_thread([&](){ waiting(ms,p); });
std::thread ms_nolambda(waiting<std::chrono::milliseconds>,ms,p);
The lambda version works fine but the one without the lambda gives compilation errors:
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:129:2: error: static_assert failed due to requirement '__is_invocable<void (*)(std::chrono::duration<long, std::ratio<1, 1000>>, Printer &), std::chrono::duration<long, std::ratio<1, 1000>>, Printer>::value' "std::thread arguments must be invocable after conversion to rvalues" static_assert( __is_invocable<typename decay<_Callable>::type, ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ chrono.cpp:60:15: note: in instantiation of function template specialization 'std::thread::thread<void (&)(std::chrono::duration<long, std::ratio<1, 1000>>, Printer &), std::chrono::duration<long, std::ratio<1, 1000>> &, Printer &, void>' requested here std::thread ms_nolambda(waitingstd::chrono::milliseconds,ms,p);
In file included from chrono.cpp:2: In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/future:48: /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:251:31: error: no type named 'type' in 'std::thread::_Invoker<std::tuple<void ()(std::chrono::duration<long, std::ratio<1, 1000>>, Printer &), std::chrono::duration<long, std::ratio<1, 1000>>, Printer>>::__result<std::tuple<void ()(std::chrono::duration<long, std::ratio<1, 1000>>, Printer &), std::chrono::duration<long, std::ratio<1, 1000>>, Printer>>' typename __result<_Tuple>::type ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:203:13: note: in instantiation of template class 'std::thread::_Invoker<std::tuple<void (*)(std::chrono::duration<long, std::ratio<1, 1000>>, Printer &), std::chrono::duration<long, std::ratio<1, 1000>>, Printer>>' requested here _Callable _M_func;
I don't fully understand what clang++ is trying to tell me. But obviously something is going wrong with the template instantiation as std::thread's constructor sees it. If I make my Printer a global variable and just take it out of the function arguments both lambda and non-lambda thread calls compile and work fine.
Am I doing something stupid or is this just "not how thread creation works" for some reason? Or am I doing something I am not supposed to do with regard to having one templated argument and one non-templated argument for the waiting function?
Thanks!