C++ 多线程和传递模板参数 <typename T>(T arg)
C++ multithreading and passing templated arguments <typename T>(T arg)
我有这段代码,没有任何问题:
void function_exit(dispatcher& d) { /* .. */ }
// ...
std::thread th(function_exit, std::ref(main_disp));
th.detach();
现在我尝试创建另一个 class,其中包含 std::thread
,这会在编译时产生错误
thread_control mtc;
mtc.create<dispatcher&>(function_exit, main_disp);
这里是创建函数:(请阅读描述问题的注释文本)
template<typename Arg>
inline bool thread_control::create(void(*function)(Arg), Arg value)
{
bool ok = false;
if (created == false)
{
created = true;
if (typeid(Arg).hash_code() == typeid(void).hash_code())
{
// this produce thread(50,5): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)'
// type_traits(1583): message : see declaration of 'std::invoke'
// thread(50,5): message : With the following template arguments:
// thread(50,5): message : '_Callable=void (__cdecl *)(Arg)'
m_thread = std::thread(function);
}
else
{
if (std::is_reference<Arg>::value)
{
// if only this function is used, program is compiled without errors and runs without problem.
// (when i comment functions which are problematic and this function is uncomented)
m_thread = std::thread(function, std::ref(value));
}
else
{
// this function produce this errors:
// 2>...\Visual Studio 2019\VC\Tools\MSVC.28.29910\include\thread(65): message : see reference to function template instantiation 'unsigned int (__stdcall *std::thread::_Get_invoke<_Tuple,0,1>(std::integer_sequence<size_t,0,1>) noexcept)(void *)' being compiled
// thread(50,5): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...) noexcept(<expr>)'
// type_traits(1589): message : see declaration of 'std::invoke'
// thread(50,5): message : With the following template arguments:
// thread(50,5): message : '_Callable=void (__cdecl *)(Arg)'
// thread(50,5): message : '_Ty1=dispatcher'
// thread(50,5): message : '_Types2={}'
// thread(50,5): error C2780: 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)': expects 1 arguments - 2 provided
// type_traits(1583): message : see declaration of 'std::invoke'
m_thread = std::thread(function, value);
}
}
ok = true;
}
return ok;
}
我的 m_thread = std::thread(...);
函数有什么问题会抛出这些编译错误?或者我做错了什么?
if (std::is_reference<Arg>::value)
对于给定的 Arg
,这当然会计算为 true
或 false
。
然而两者这个条件为真时执行的代码,和这个条件为假时执行的代码必须是有效的 C++.
m_thread = std::thread(function, value);
如果 Arg
是引用,则这不是有效的 C++。即使 if
条件的计算结果为 true
,并且不会执行,这个 仍然必须是有效的 C++.
此处可以使用两种基本方法。
在 C++17 及更高版本中使用 if constexpr
。
使用 C++14 及更早版本,您需要重写整个内容以使用特化(整个模板函数的特化,或者将相关逻辑移动到模板 类 中并特化他们)。
我有这段代码,没有任何问题:
void function_exit(dispatcher& d) { /* .. */ }
// ...
std::thread th(function_exit, std::ref(main_disp));
th.detach();
现在我尝试创建另一个 class,其中包含 std::thread
,这会在编译时产生错误
thread_control mtc;
mtc.create<dispatcher&>(function_exit, main_disp);
这里是创建函数:(请阅读描述问题的注释文本)
template<typename Arg>
inline bool thread_control::create(void(*function)(Arg), Arg value)
{
bool ok = false;
if (created == false)
{
created = true;
if (typeid(Arg).hash_code() == typeid(void).hash_code())
{
// this produce thread(50,5): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)'
// type_traits(1583): message : see declaration of 'std::invoke'
// thread(50,5): message : With the following template arguments:
// thread(50,5): message : '_Callable=void (__cdecl *)(Arg)'
m_thread = std::thread(function);
}
else
{
if (std::is_reference<Arg>::value)
{
// if only this function is used, program is compiled without errors and runs without problem.
// (when i comment functions which are problematic and this function is uncomented)
m_thread = std::thread(function, std::ref(value));
}
else
{
// this function produce this errors:
// 2>...\Visual Studio 2019\VC\Tools\MSVC.28.29910\include\thread(65): message : see reference to function template instantiation 'unsigned int (__stdcall *std::thread::_Get_invoke<_Tuple,0,1>(std::integer_sequence<size_t,0,1>) noexcept)(void *)' being compiled
// thread(50,5): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...) noexcept(<expr>)'
// type_traits(1589): message : see declaration of 'std::invoke'
// thread(50,5): message : With the following template arguments:
// thread(50,5): message : '_Callable=void (__cdecl *)(Arg)'
// thread(50,5): message : '_Ty1=dispatcher'
// thread(50,5): message : '_Types2={}'
// thread(50,5): error C2780: 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)': expects 1 arguments - 2 provided
// type_traits(1583): message : see declaration of 'std::invoke'
m_thread = std::thread(function, value);
}
}
ok = true;
}
return ok;
}
我的 m_thread = std::thread(...);
函数有什么问题会抛出这些编译错误?或者我做错了什么?
if (std::is_reference<Arg>::value)
对于给定的 Arg
,这当然会计算为 true
或 false
。
然而两者这个条件为真时执行的代码,和这个条件为假时执行的代码必须是有效的 C++.
m_thread = std::thread(function, value);
如果 Arg
是引用,则这不是有效的 C++。即使 if
条件的计算结果为 true
,并且不会执行,这个 仍然必须是有效的 C++.
此处可以使用两种基本方法。
在 C++17 及更高版本中使用
if constexpr
。使用 C++14 及更早版本,您需要重写整个内容以使用特化(整个模板函数的特化,或者将相关逻辑移动到模板 类 中并特化他们)。