【发布时间】:2016-01-24 11:40:06
【问题描述】:
我想要一个包装线程函数,即一个由线程执行的函数,它做一些额外的事情,然后调用用户函数。
template<class F, class... Args>
void wrapper(F&& user_function, Args&&... args) {
// do some extra stuff
user_function(args); // maybe I need to forward args
// do some extra stuff
}
好的,这可能是一个很好的包装器,所以我需要一个使用这个包装器功能并允许用户产生自己的线程的管理器:
class ThreadManager {
public:
template<class F, class... Args>
std::thread newThread(F&& f, Args&&... args) {
return std::thread(thread_wrapper<F,Args...>, std::forward<F>(f), std::forward<Args>(args)...);
}
};
这样,线程管理器应该生成一个使用包装函数的线程,该函数反过来做额外的工作并调用用户函数。
但编译器现在说:尝试使用已删除的函数。
错误在线程头中:
template <class _Fp, class ..._Args, size_t ..._Indices>
inline _LIBCPP_INLINE_VISIBILITY
void
__thread_execute(tuple<_Fp, _Args...>& __t, __tuple_indices<_Indices...>)
{
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
}
我错过了什么/做错了什么?
[编辑]
使用测试:
void foo(int i) {
std::cout << "foo: " << i << std::endl;
}
int main(int argc, const char *argv[]) {
ThreadManager mgr;
auto t = mgr.newThread(foo, 10);
t.detach();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
return 0;
}
我正在使用带有 LLVM 编译器的 Xcode 7.1,但在 FreeBSD clang 3.3 上也失败了。
Xcode 错误是:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:337:5:错误:尝试使用已删除的函数 __invoke(_VSTD::move(_VSTD::get(__t)), _VSTD::move(_VSTD::get<_indices>(__t))...); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:347:5:注意:在函数模板特化'std::__1的实例化中: :__thread_execute' 在这里请求 __thread_execute(*__p, _Index()); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:359:42:注意:在函数模板特化'std::__1的实例化中: :__thread_proxy >' 在这里请求 int __ec = pthread_create(&__t_, 0, &__thread_proxy<_gp>, __p.get());
【问题讨论】:
-
发布确切的错误。你使用什么编译器和版本?
-
如果您使用普通函数而不是仿函数,您在 melpon.org 上的示例将失败...
-
请注意,显式使用
thread_wrapper<F, Args...>会将您完美的转发F&&和Args&&参数变成实际的右值引用参数。
标签: multithreading c++11