带有run方法的std :: thread包装器

时间:2018-02-01 12:38:06

标签: c++11 gcc c++14

我正在尝试使用run方法为std :: thread编写一个包装器,这将允许线程仅在调用run时执行。

       class ThreadRAII_WITHRUN {                                                                                                                                                 

public:                                                                                                                                                                    
enum class DtorAction { join, detach };                                                                                                                                

template< class Function, class... Args >                                                                                                                              
ThreadRAII_WITHRUN(DtorAction a,Function&& f, Args&&... args)                                                                                                          
: action(a)                                                                                                                                                            
, t(std::thread([&](){pro.get_future().wait(); std::forward<Function>(f)(std::forward<Args>(args)...);}))                                                              
{                                                                                                                                                                      
}                                                                                                                                                                      

void run()                                                                                                                                                             
{                                                                                                                                                                      
    pro.set_value();                                                                                                                                                   
}                                                                                                                                                                      

~ThreadRAII_WITHRUN()                                                                                                                                                  
{                                                                                                                                                                      
if (t.joinable()) { // joinability test                                                                                                                                
    if (action == DtorAction::join) {                                                                                                                                  
    t.join();                                                                                                                                                          
    } else {                                                                                                                                                           
    t.detach();                                                                                                                                                        
    }                                                                                                                                                                  
}                                                                                                                                                                      
}                                                                                                                                                                      
ThreadRAII_WITHRUN(ThreadRAII_WITHRUN&&) = default; // support                                                                                                         
ThreadRAII_WITHRUN& operator=(ThreadRAII_WITHRUN&&) = default; // moving                                                                                               
std::thread& get() { return t; }                                                                                                                           

private: // as before                                                                                                                                                      
DtorAction action;                                                                                                                                                     
std::promise<void> pro;                                                                                                                                                
std::thread t;                                                                                                                                                         

};     

此代码使用gcc6.1.0编译,但不使用gcc4.8.5

编译

使用gcc4.8.5和-std = c ++ 11标志我得到以下错误。

g++ -std=c++11 thread.cpp -pthread
thread.cpp: In lambda function:
thread.cpp:74:94: error: parameter packs not expanded with â...â:
  , t(std::thread([&](){pro.get_future().wait(); std::forward<Function>(f)(std::forward<Args>(args)...);}))
                                                                                              ^
thread.cpp:74:94: note:         âargsâ
thread.cpp: In instantiation of âstruct ThreadRAII_WITHRUN::ThreadRAII_WITHRUN(ThreadRAII_WITHRUN::DtorAction, Function&&, Args&& ...) [with Function = threadwithraii_run()::__lambda10; Args = {int}]::__lambda9â:
thread.cpp:74:106:   required from âThreadRAII_WITHRUN::ThreadRAII_WITHRUN(ThreadRAII_WITHRUN::DtorAction, Function&&, Args&& ...) [with Function = threadwithraii_run()::__lambda10; Args = {int}]â
thread.cpp:104:117:   required from here
thread.cpp:74:94: error: using invalid field âThreadRAII_WITHRUN::ThreadRAII_WITHRUN(ThreadRAII_WITHRUN::DtorAction, Function&&, Args&& ...)::__lambda9::__argsâ

今天知道同样的原因吗?

1 个答案:

答案 0 :(得分:0)

有点偏离主题,lambda通过引用捕获构造函数参数。到run被调用时,这些引用中的一些或全部可能已变得无效。按值获取参数可能更安全,例如:

std::thread([=](){ ... })) 
             ^
             |
             capture by value