2017-07-04 61 views
0

我無法編譯下面的程序。爲什麼std :: move不能使用std :: list

void toSin(std::list<double>&& list) 
{ 
    std::for_each(list.begin(), list.end(), [](double& x) 
    { 
     x = sin(x); 
    }); 
} 

int main() 
{ 
    std::list<double> list; 
    const double pi = 3.141592; 
    const double epsilon = 0.0000001; 
    for (double x = 0.0; x < 2 * pi + epsilon; x = x + pi/16) 
    { 
     list.push_back(x); 
    } 
    // Start thread 
    std::thread th(toSin, std::move(list)); 
    th.join(); 
    return 0; 
} 

我得到>錯誤C2664: 'void (std::list<double,std::allocator<_Ty>> &&)':無法從 'std::list<double,std::allocator<_Ty>>' 轉換參數1 'std::list<double,std::allocator<_Ty>> &&'

+0

重現I can not 。你使用的是哪個版本的視覺工作室?請注意,我在一堆丟失的標題中添加了。 – user4581301

+3

行std :: thread th(toSin,std :: move(list));'暗示你不應該迭代超過'list',因爲它被移走了。但是你試着在下一行上迭代它。 –

+0

Visual Studio 2013 –

回答

0

我覺得你的編譯器是錯在這裏。衰減(複製)的值類型應該可以綁定到右值引用。

反正看看this quote from the documentation

3)創建新的std :: thread對象,並與執行線程關聯。執行的新線程開始執行

std::invoke(decay_copy(std::forward<Function>(f)), decay_copy(std::forward<Args>(args))...); 

基本上任何你作爲參數傳遞給std::thread構造函數將被複製作爲函數參數的函數。

也知道你的功能將工作得很好,如果你讓它接受std::list變量的值而不是右值引用。見Correct usage of rvalue references as parameters更多


如果你的目的是傳遞給一個變量線程函數的引用,我經常這樣做的方法是用一個lambda

std::list<double> lst; 
auto th = std::thread{[&lst]() { 
    toSin(lst); 
}}; 

但你也可以使用std::ref爲同樣的效果。我個人覺得lambda方法更清晰。

std::list<double> lst; 
auto th = std::thread{toSin, std::ref(lst)}; 

Also as correctly pointed out in the comments,你必須在你的代碼中的競爭條件,你應該用mutex防止,或等待線程完成

auto th = std::thread{[&lst]() { 
    toSin(lst); 
}}; 
th.join(); 

// then iterate and print out 
+0

更新了上面的代碼,我只想爲工作線程設置一個唯一的內存以避免同步問題。 –

+0

@NARESHKITTUR如果你這樣做,但是,你打算如何在主線程中打印出列表? – Curious

+0

的確,我無法在主線程中使用該列表。我將不得不在工作線程本身中處理/打印列表。所以爲了解決這個問題,我應該通過互斥體的引用來傳遞列表。 –

0

我認爲你可能會錯過一些#include ,該代碼適用於Visual Studio 2015

#include <algorithm> 
#include <list> 
#include <thread> 
void toSin(std::list<double>&& list) 
{ 
    std::for_each(list.begin(), list.end(), [](double& x) 
    { 
     x = sin(x); 
    }); 
} 

int main() 
{ 
    std::list<double> list; 
    const double pi = 3.141592; 
    const double epsilon = 0.0000001; 
    for (double x = 0.0; x < 2 * pi + epsilon; x = x + pi/16) 
    { 
     list.push_back(x); 
    } 
    // Start thread 
    std::thread th(toSin, std::move(list)); 
    th.join(); 
    return 0; 
} 
+0

Visual Studio 2015不是Visual Studio 2013. 2013在其C++ 11支持方面存在漏洞。沒有編譯的可能性很大。我不能輕鬆訪問2013年,直到漏洞被填充時才能看到升級的重點,所以我沒有副本來試用。 – user4581301

相關問題