我正在尝试使用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â
今天知道同样的原因吗?
答案 0 :(得分:0)
有点偏离主题,lambda通过引用捕获构造函数参数。到run
被调用时,这些引用中的一些或全部可能已变得无效。按值获取参数可能更安全,例如:
std::thread([=](){ ... }))
^
|
capture by value