使用此应用程序线程包装器的唯一目的是确保在每个派生线程上一致地调用一些代码。我原以为这很简单,但是std::thread构造函数和参数传递相当复杂,我在这里遇到了非常隐蔽的构建错误。
这是我要做的一个简单的例子:
#include <thread>
class AppThread : public std::thread
{
template< class Function, class... Args >
static void wrap( Function&& f, Args&&... args )
{
//Some code
f( std::forward<Args>( args )... );
}
public:
template< class Function, class... Args >
explicit AppThread( Function&& f, Args&&... args ) : std::thread( AppThread::wrap<Function,Args...>,
std::forward<Function>( f ), std::forward<Args>( args )... )
{}
};
void runA() {}
void runB( int x ) {}
main()
{
AppThread thread1 = AppThread( runA );
//AppThread thread2 = AppThread( runB, 5 );
}
我希望能在任何地方访问AppThread标准:螺纹因此,扩展和重写构造函数似乎是最好的方法。但是将这些参数传递给我的包装方法会导致一连串的错误(gcc7.2)
In file included from thread_wrap.cpp:1:0:
gcc-7.2.0/include/c++/7.2.0/thread: In instantiation of âstruct std::thread::_Invoker<std::tuple<void (*)(void (&)()), void (*)()> >â:
gcc-7.2.0/include/c++/7.2.0/thread:127:22: required from âstd::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(void (&)()); _Args = {void (&)()}]â
thread_wrap.cpp:15:130: required from âAppThread::AppThread(Function&&, Args&& ...) [with Function = void (&)(); Args = {}]â
thread_wrap.cpp:24:41: required from here
gcc-7.2.0/include/c++/7.2.0/thread:240:2: error: no matching function for call to âstd::thread::_Invoker<std::tuple<void (*)(void (&)()), void (*)()> >::_M_invoke(std::thread::_Invoker<std::tuple<void (*)(void (&)()), void (*)()> >::_Indices)â
operator()()
^~~~~~~~
gcc-7.2.0/include/c++/7.2.0/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (*)(void (&)()), void (*)()>]
_M_invoke(_Index_tuple<_Ind...>)
^~~~~~~~~
gcc-7.2.0/include/c++/7.2.0/thread:231:4: note: template argument deduction/substitution failed:
gcc-7.2.0/include/c++/7.2.0/thread: In substitution of âtemplate<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (*)(void (&)()), void (*)()> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1}]â:
gcc-7.2.0/include/c++/7.2.0/thread:240:2: required from âstruct std::thread::_Invoker<std::tuple<void (*)(void (&)()), void (*)()> >â
gcc-7.2.0/include/c++/7.2.0/thread:127:22: required from âstd::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(void (&)()); _Args = {void (&)()}]â
thread_wrap.cpp:15:130: required from âAppThread::AppThread(Function&&, Args&& ...) [with Function = void (&)(); Args = {}]â
thread_wrap.cpp:24:41: required from here
gcc-7.2.0/include/c++/7.2.0/thread:233:29: error: no matching function for call to â__invoke(std::__tuple_element_t<0, std::tuple<void (*)(void (&)()), void (*)()> >, std::__tuple_element_t<1, std::tuple<void (*)(void (&)()), void (*)()> >)â
-> decltype(std::__invoke(_S_declval<_Ind>()...))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
In file included from gcc-7.2.0/include/c++/7.2.0/tuple:41:0,
from gcc-7.2.0/include/c++/7.2.0/bits/unique_ptr.h:37,
from gcc-7.2.0/include/c++/7.2.0/memory:80,
from gcc-7.2.0/include/c++/7.2.0/thread:39,
from thread_wrap.cpp:1:
gcc-7.2.0/include/c++/7.2.0/bits/invoke.h:89:5: note: candidate: template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...)
__invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~~~
gcc-7.2.0/include/c++/7.2.0/bits/invoke.h:89:5: note: template argument deduction/substitution failed:
gcc-7.2.0/include/c++/7.2.0/bits/invoke.h: In substitution of âtemplate<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = void (*)(void (&)()); _Args = {void (*)()}]â:
gcc-7.2.0/include/c++/7.2.0/thread:233:29: required by substitution of âtemplate<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (*)(void (&)()), void (*)()> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1}]â
gcc-7.2.0/include/c++/7.2.0/thread:240:2: required from âstruct std::thread::_Invoker<std::tuple<void (*)(void (&)()), void (*)()> >â
gcc-7.2.0/include/c++/7.2.0/thread:127:22: required from âstd::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(void (&)()); _Args = {void (&)()}]â
thread_wrap.cpp:15:130: required from âAppThread::AppThread(Function&&, Args&& ...) [with Function = void (&)(); Args = {}]â
thread_wrap.cpp:24:41: required from here
gcc-7.2.0/include/c++/7.2.0/bits/invoke.h:89:5: error: no type named âtypeâ in âstruct std::__invoke_result<void (*)(void (&)()), void (*)()>â