[英]Passing move-only function arguments to boost::thread constructor
The following works for std::thread
.以下适用于
std::thread
。 It prints 10 as output, which is what I desire.它将 10 打印为 output,这是我想要的。
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();
}
But, similar attempt with Boost 1.72 fails to compile但是,使用 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 >
I find this surprising, because the documentation for boost::thread states the following:我觉得这很令人惊讶,因为 boost::thread 的文档说明了以下内容:
Thread Constructor with arguments template <class F,class A1,class A2,...> thread(F f,A1 a1,A2 a2,...);
带有 arguments 模板的线程构造函数 <class F,class A1,class A2,...> thread(F f,A1 a1,A2 a2,...);
Preconditions: F and each An must be copyable or movable.
前提条件:F 和每个 An 必须是可复制的或可移动的。
Since I am passing a std::unique_ptr
as argument, I am meeting the 'movable' criterion.由于我将
std::unique_ptr
作为参数传递,因此我满足“可移动”标准。 So, I wonder why is boost thread constructing the std::unique_ptr
?所以,我想知道为什么 boost 线程构造
std::unique_ptr
? Shouldn't it move the std::unique_ptr into the thread object, and then move it further into the thread function like the implementation for std::thread
does?它不应该像
std::thread
的实现那样将 std::unique_ptr 移动到线程 object 中,然后将其进一步移动到线程 function 中吗?
Per documentation, boost::thread
uses the arguments in exactly the same way boost::bind
does, and this combination of function and argument is unsuitable for boost::bind
(and for std::bind
for that matter).根据文档,
boost::thread
使用 arguments 的方式与boost::bind
完全相同,并且 function 和参数的组合不适合boost::bind
(也不适用于std::bind
)。
std::bind(foo, std::move(in))(); // error
boost::bind(foo, std::move(in))(); // error
std::thread
is more robust than either std::bind
or boost::bind
. std::thread
比std::bind
或boost::bind
更健壮。
If you need to move the argument to foo
, you need to wrap it in a function or a lambda that accepts it by non-const lvalue reference and moves it to foo
.如果您需要将参数移动到
foo
,则需要将其包装在 function 或 lambda 中,通过非常量左值引用接受它并将其移动到foo
。 Otherwise, just change foo
to accept a non-const lvalue reference argument.否则,只需更改
foo
以接受非常量左值引用参数。
Looks like a bug in Boost.Thread documentation.看起来像Boost.Thread文档中的错误。 By default it doesn't support move-only arguments since it passes them through to
boost::bind
by-value instead of forwarding.默认情况下,它不支持仅移动 arguments 因为它将它们传递给
boost::bind
按值而不是转发。
But there's a flag BOOST_THREAD_PROVIDES_VARIADIC_THREAD
that enables boost::thread
rvalue-constructors.但是有一个标志
BOOST_THREAD_PROVIDES_VARIADIC_THREAD
可以启用boost::thread
右值构造函数。 It is set automatically when another poorly documented variable, BOOST_THREAD_VERSION
> 4.当另一个记录不充分的变量
BOOST_THREAD_VERSION
> 4 时,它会自动设置。
#define BOOST_THREAD_VERSION 5
#include <boost/thread.hpp>
. . .
Another possible workaround is to use a lambda.另一种可能的解决方法是使用 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();
}
The boost thread library uses boost bind, and boost bind assumes you can call the callable repeatedly, so doesn't move out of it. boost线程库使用boost bind,boost bind假设你可以重复调用callable,所以不要移出它。 You can fake it.
你可以伪造它。
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);
};
then然后
auto in = std::make_unique<int>(10);
boost::thread t(foo, move_it(in));
t.join();
what this does is wrap in
in a type that, when cast to T
, moves instead of copies.它的作用是包装
in
一个类型中,当它转换为T
时,它会移动而不是复制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.