[英]using std::move in std::thread
I encountered yet another problem with std::thread
& this time while applying std::move
to swap 2 values. 我在使用
std::move
到swap 2值时遇到了std::thread
另一个问题。 My code says :- 我的代码说: -
#include <iostream>
#include <thread>
using namespace std;
void swapno (int &&a, int &&b)
{
int temp=move(a);
a=move(b);
b=move(temp);
}
int main()
{
int x=5, y=7;
cout << "x = " << x << "\ty = " << y << "\n";
// swapno (move(x), move(y)); // this works fine
thread t (swapno, move(x), move(y));
t.join();
cout << "x = " << x << "\ty = " << y << "\n";
return 0;
}
Output :- 输出: -
x = 5 y = 7
x = 5 y = 7
Now what's wrong in this method ? 现在这个方法有什么问题? Why is such the code showing such a behaviour ?
为什么这样的代码显示出这样的行为? How do I correct it ?
我该如何纠正?
It's because the thread
constructor you're calling 这是因为你正在调用的
thread
构造函数
copies/moves all arguments (both the function object f and all args...) to thread-accessible storage as if by the function:
将所有参数(包括函数对象f和所有参数...)复制/移动到线程可访问的存储,就像通过函数一样:
template <class T>
typename decay<T>::type decay_copy(T&& v) {
return std::forward<T>(v);
}
And std::decay
will remove cv-qualifiers, which includes r-value references. 并且
std::decay
将删除cv-qualifiers,其中包括r值引用。
Thus, when std::thread
is copy/moving arguments to thread-accessible storage, it's essentially move constructing it's own int
s from the ones you provided, and because a move
on an int
is simply a copy, when you perform swapno
on its values, you're doing it on copies. 因此,当
std::thread
是复制/移动参数到线程可访问的存储时,它本质上是从你提供的那些移动构造它自己的 int
,并且因为int
上的move
只是一个副本,当你swapno
执行swapno
时价值观,你是在副本上做的。
To correct it, use std::ref
plus swap
: 要更正它,请使用
std::ref
plus swap
:
std::thread t ([](int& a, int& b){std::swap(a, b);}, std::ref(x), std::ref(y));
t.join();
In layman's terms, thread's constructor accepts temporaries/rvalues to the arguments passed to the function. 通俗地说,线程的构造函数接受传递给函数的参数的temporaries / rvalues。 Therefore you have to wrap it with a reference_wrapper, which is a value but wraps the underlying reference (what std::ref does).
因此,您必须使用reference_wrapper包装它,这是一个值但包装底层引用(std :: ref的作用)。
The code below does the trick with std::swap out of the box. 下面的代码使用std :: swap开箱即用。 Using std::swap as argument to thread (or std::function) causes and ambiguous overload (which surprised me too).
使用std :: swap作为thread(或std :: function)的参数导致和模糊的重载(这也让我感到惊讶)。
int main(int argc, char* argv[])
{
int x = 5, y = 7;
std::cout << "x(" << x << ")" << " y(" << y <<")" << std::endl;
void (*pf)(int& x, int& y) = std::swap<int>;
std::thread t1(pf, std::ref<int>(x), std::ref<int>(y));
t1.join();
std::cout << "x(" << x << ")" << " y(" << y <<")" << std::endl;
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.