Here is a minimal case:
#include <iostream>
#include <functional>
#include <thread>
void fun(void *args) {}
int main() {
std::thread thread_id(fun, NULL);
}
g++ compiles fail:
[firstlove@manjaro misc]$ g++ thread_and_shared_resources.cpp -lpthread -std=c++17
In file included from thread_and_shared_resources.cpp:3:
/usr/include/c++/9.3.0/thread: In instantiation of 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(void*); _Args = {long int}; <template-parameter-1-3> = void]':
thread_and_shared_resources.cpp:6:34: required from here
/usr/include/c++/9.3.0/thread:120:44: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
120 | typename decay<_Args>::type...>::value,
| ^~~~~
/usr/include/c++/9.3.0/thread: In instantiation of 'struct std::thread::_Invoker<std::tuple<void (*)(void*), long int> >':
/usr/include/c++/9.3.0/thread:131:22: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(void*); _Args = {long int}; <template-parameter-1-3> = void]'
thread_and_shared_resources.cpp:6:34: required from here
/usr/include/c++/9.3.0/thread:243:4: error: no type named 'type' in 'struct std::thread::_Invoker<std::tuple<void (*)(void*), long int> >::__result<std::tuple<void (*)(void*), long int> >'
243 | _M_invoke(_Index_tuple<_Ind...>)
| ^~~~~~~~~
/usr/include/c++/9.3.0/thread:247:2: error: no type named 'type' in 'struct std::thread::_Invoker<std::tuple<void (*)(void*), long int> >::__result<std::tuple<void (*)(void*), long int> >'
247 | operator()()
| ^~~~~~~~
[firstlove@manjaro misc]$ g++ thread_and_shared_resources.cpp -lpthread -std=c++17
In file included from thread_and_shared_resources.cpp:3:
/usr/include/c++/9.3.0/thread: In instantiation of 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(void*); _Args = {long int}; <template-parameter-1-3> = void]':
thread_and_shared_resources.cpp:6:34: required from here
/usr/include/c++/9.3.0/thread:120:44: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
120 | typename decay<_Args>::type...>::value,
| ^~~~~
/usr/include/c++/9.3.0/thread: In instantiation of 'struct std::thread::_Invoker<std::tuple<void (*)(void*), long int> >':
/usr/include/c++/9.3.0/thread:131:22: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(void*); _Args = {long int}; <template-parameter-1-3> = void]'
thread_and_shared_resources.cpp:6:34: required from here
/usr/include/c++/9.3.0/thread:243:4: error: no type named 'type' in 'struct std::thread::_Invoker<std::tuple<void (*)(void*), long int> >::__result<std::tuple<void (*)(void*), long int> >'
243 | _M_invoke(_Index_tuple<_Ind...>)
| ^~~~~~~~~
/usr/include/c++/9.3.0/thread:247:2: error: no type named 'type' in 'struct std::thread::_Invoker<std::tuple<void (*)(void*), long int> >::__result<std::tuple<void (*)(void*), long int> >'
247 | operator()()
| ^~~~~~~~
Why NULL cannot be passed here? the standalone call to fun with NULL works just fine:
fun(NULL) // compiles happily