在std :: thread中使用std :: move

时间:2015-11-24 14:05:22

标签: c++ multithreading move

我遇到了另一个问题std::thread&这次应用std::move来交换2个值。我的代码说: -

#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;
}

输出: -

x = 5   y = 7
x = 5   y = 7

现在这种方法有什么问题?为什么这样的代码显示出这样的行为?我该如何纠正?

2 个答案:

答案 0 :(得分:3)

这是因为您正在调用thread constructor

  

复制/移动所有参数(函数对象f和all)   args ...)线程可访问的存储,就好像通过函数:

template <class T>
typename decay<T>::type decay_copy(T&& v) {
    return std::forward<T>(v);
}

std::decay将删除cv限定符,其中包括r值引用。

因此,当std::thread是复制/移动参数到线程可访问的存储时,它本质上是移动构建它自己的 int您提供的那些,并且因为move上的int只是一个副本,当您对其值执行swapno时,您就会在副本上执行此操作。

要更正它,请使用std::refswap

std::thread t ([](int& a, int& b){std::swap(a, b);}, std::ref(x), std::ref(y));
t.join();

Live Demo

答案 1 :(得分:0)

在外行人的术语中,线程的构造函数接受传递给函数的参数的临时值/右值。因此,您必须使用reference_wrapper包装它,它是一个值,但包装了底层引用(std :: ref的作用)。

下面的代码使用std :: swap开箱即用。使用std :: swap作为thread(或std :: function)的参数导致和模糊的重载(这也让我感到惊讶)。

const H = require('highland')

H((push, next) => {
  push(null, 'value to repeat')
  next()
})