我想实现一个小线程包装器,如果一个线程仍处于活动状态,或者该线程已完成其工作,它将提供信息.为此,我需要将函数及其参数传递给线程类到另一个函数.我有一个简单的实现应该可以工作,但不能让它编译,我无法弄清楚该怎么做才能使它工作.
这是我的代码:
#include#include #include #include #include class ManagedThread { public: template< class Function, class... Args> explicit ManagedThread( Function&& f, Args&&... args); bool isActive() const { return mActive; } private: volatile bool mActive; std::thread mThread; }; template< class Function, class... Args> void threadFunction( volatile bool& active_flag, Function&& f, Args&&... args) { active_flag = true; f( args...); active_flag = false; } template< class Function, class... Args> ManagedThread::ManagedThread( Function&& f, Args&&... args): mActive( false), mThread( threadFunction< Function, Args...>, std::ref( mActive), f, args...) { } static void func() { std::cout << "thread 1" << std::endl; } int main() { ManagedThread mt1( func); std::cout << "thread 1 active = " << std::boolalpha << mt1.isActive() << std::endl; ::sleep( 1); std::cout << "thread 1 active = " << std::boolalpha << mt1.isActive() << std::endl; return 0; }
我得到的编译器错误:
In file included from /usr/include/c++/5/thread:39:0, from prog.cpp:4: /usr/include/c++/5/functional: In instantiation of 'struct std::_Bind_simple, void (*)()))(volatile bool&, void (&)())>': /usr/include/c++/5/thread:137:59: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(volatile bool&, void (&)()); _Args = {std::reference_wrapper , void (&)()}]' prog.cpp:28:82: required from 'ManagedThread::ManagedThread(Function&&, Args&& ...) [with Function = void (&)(); Args = {}]' prog.cpp:35:28: required from here /usr/include/c++/5/functional:1505:61: error: no type named 'type' in 'class std::result_of , void (*)()))(volatile bool&, void (&)())>' typedef typename result_of<_Callable(_Args...)>::type result_type; ^ /usr/include/c++/5/functional:1526:9: error: no type named 'type' in 'class std::result_of , void (*)()))(volatile bool&, void (&)())>' _M_invoke(_Index_tuple<_Indices...>) ^
现场示例如下:https://ideone.com/jhBF1q
在错误消息,你可以看到其中的差别void (*)()
VS void (&)()
.这是因为性病::线程的构造函数的参数std::decay
编.
另外还添加std::ref
到f
:
template< class Function, class... Args> ManagedThread::ManagedThread( Function&& f, Args&&... args): mActive( false), mThread( threadFunction< Function, Args...>, std::ref(mActive), std::ref(f), std::forward(args)...) { }
@ O'Neil的回答是正确的,但我想提供一个简单的lambda方法,因为你已将其标记为C++14
.
templateManagedThread::ManagedThread(Function&& f, Args&&... args): mActive(false), mThread([&] /*()*/ { // uncomment if C++11 compatibility needed mActive = true; std::forward (f)(std::forward (args)...); mActive = false; }) {}
这将不再需要外部功能.