C++ 为什么std::thread';s执行函数';s void*参数?
以下是一个最基本的情况:C++ 为什么std::thread';s执行函数';s void*参数?,c++,multithreading,null,C++,Multithreading,Null,以下是一个最基本的情况: #包括 #包括 #包括 void fun(void*args){} int main(){ std::thread_id(fun,NULL); } g++编译失败: [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/
#包括
#包括
#包括
void fun(void*args){}
int main(){
std::thread_id(fun,NULL);
}
g++编译失败:
[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()()
| ^~~~~~~~
NULL
在您的实现中扩展为0
,并且0
是一个整数,而不是指针。它在某些上下文中可转换为指针,但在其他上下文中不能转换为指针;这是后者的一个例子
使用
nullptr
,它解决了许多类似的问题。TL;Dr:<强> >代码> null 是遗留C++。在现代C++中,使用<强>代码> NulLPTR < /代码> <强>作为对NULL
?使用NULL
对fun的独立调用工作正常
<> 1)在GLUBC中,C++中的代码>空是定义为<代码> 0L< /代码> 1 < /P>
2) std::thread
的构造函数使用std::invoke
将其参数转发给可调用参数。转发右值0L
时,它首先成为一个变量(引用类型)
3)C++中的空指针隐式转换规则在
中指定 空指针常量是值为零的整数文本或类型为std的prvalue::nullptr\ut
。空指针常量可以转换为指针类型;结果是该类型的空指针值,并且可以与对象指针或函数指针类型的所有其他值区分开来。这种转换称为空指针转换
这意味着C++允许积分字值为0(因此,字面上是代码> 0 < /COD>,<代码> 0L,<代码> 0U <代码>等),但不是其他积分值,可隐式转换为指针类型:
void fun(void* args) {}
int main() {
fun(0); // OK
int arg = 0;
fun(arg); // error: invalid conversion from 'int' to 'void*'
}
现在,由于std::invoke
是一个模板,因此根本原因错误“从'long int'到'void'*'的无效转换”属于SFINAE规则,并被默默地吞没,这给您留下了一个关于std::thread
参数问题的模糊错误
解决方法是使用NULL ptr
而不是NULL
< C模式>代码> null >代码>(空隙*)0 < /C> >,但是在C++中是禁止的。< /P>尝试用
std::any
。谢谢。我知道nullptr
在这里工作得很好。但是我不明白为什么这里不能应用NULL
。
void fun(void* args) {}
int main() {
fun(0); // OK
int arg = 0;
fun(arg); // error: invalid conversion from 'int' to 'void*'
}