如何解决将仅移动函数参数传递给 boost::thread 构造函数
以下适用于 std::thread
。它打印 10 作为输出,这正是我想要的。
void foo(std::unique_ptr<int> && in) {
std::cout << *in;
}
int main(){
auto in = std::make_unique<int>(10);
std::thread t(foo,std::move(in));
t.join();
}
但是,与 Boost 1.72 的类似尝试无法编译
void foo(std::unique_ptr<int> && in) {
std::cout << *in;
}
int main(){
auto in = std::make_unique<int>(10);
boost::thread t(foo,std::move(in));
t.join();
}
Error : note: copy constructor of 'list1<boost::_bi::value<std::unique_ptr<int>>>' is implicitly deleted because base class 'storage1<boost::_bi::value<std::unique_ptr<int>>>' has a deleted copy constructor
template< class A1 > class list1: private storage1< A1 >
我觉得这很奇怪,因为 boost::thread 的文档说明如下:
带参数的线程构造函数
模板
先决条件: F 和每个 An 必须是可复制或可移动的。
由于我将 std::unique_ptr
作为参数传递,因此我满足了“可移动”标准。所以,我想知道为什么 boost 线程会构造 std::unique_ptr
?难道它不应该像 std::thread
的实现那样将 std::unique_ptr 移动到线程对象中,然后将其进一步移动到线程函数中吗?
解决方法
根据文档,boost::thread
以与 boost::bind
完全相同的方式使用参数,并且函数和参数的这种组合不适用于 boost::bind
(对于 std::bind
那件事)。
std::bind(foo,std::move(in))(); // error
boost::bind(foo,std::move(in))(); // error
std::thread
比 std::bind
或 boost::bind
更健壮。
如果您需要将参数移动到 foo
,您需要将它包装在一个函数或一个通过非常量左值引用接受它的 lambda 中并将其移动到 foo
。否则,只需更改 foo
以接受非常量左值引用参数。
看起来像 Boost.Thread 文档中的错误。默认情况下,它不支持仅移动参数,因为它将它们传递给 boost::bind
按值而不是转发。
但是有一个标志 BOOST_THREAD_PROVIDES_VARIADIC_THREAD
可以启用 boost::thread
右值构造函数。当另一个记录不佳的变量 BOOST_THREAD_VERSION
> 4 时,它会自动设置。
#define BOOST_THREAD_VERSION 5
#include <boost/thread.hpp>
. . .
另一种可能的解决方法是使用 lambda。
void foo(std::unique_ptr<int> in) {
std::cout << *in;
}
int main() {
auto in = std::make_unique<int>(10);
boost::thread t([in = std::move(in)]() mutable { foo(std::move(in)); });
t.join();
}
,
boost 线程库使用boost bind,boost bind 假设你可以重复调用callable,所以不会移出它。你可以伪造它。
template<class T>
struct move_it_t {
T t;
operator T(){ return std::move(t); }
};
template<class T>
move_it_t<typename std::decay<T>::type> move_it(T&& t)
return std::move(t);
};
然后
auto in = std::make_unique<int>(10);
boost::thread t(foo,move_it(in));
t.join();
这样做是将 in
包裹在一种类型中,当转换为 T
时,它会移动而不是复制。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。