2017-07-04 23 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>> &&'

+0

再現私はできません。どのバージョンのVisual Studioを使用していますか?あなたに気をつけて、私は一杯の紛失したヘッダーを追加しました。 – user4581301

+3

'std :: thread th(toSin、std :: move(list));'行は、移動しているので、その点を越えて 'list'を反復してはならないことを意味します。しかし、あなたはそれを次の行で繰り返そうとします。 –

+0

Visual Studio 2013 –

答えて

0

に 'std::list<double,std::allocator<_Ty>>' から引数1を変換することはできませんが。崩壊(コピー)された値の型は、値の参照にバインド可能である必要があります。

とにかくthis quote from the documentation

3を見て)新しいのstd ::スレッドオブジェクトを作成し、実行スレッドに関連付けます。実行の新しいスレッドを使用すると、関数の関数の引数としてコピーされますstd::threadのコンストラクタに引数として渡す

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

基本的には何の実行を開始します。

std::list変数をrvalue参照ではなく値で受け入れるようにすると、関数が正常に機能することもわかります。あなたの意図は、私はそれを行う方法は、通常、ラムダ

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

である。しかし、あなたが使用することもでき、スレッド関数に変数への参照を渡すことであれば、より


ためCorrect usage of rvalue references as parametersを参照してくださいstd::ref同じ効果のために。私は個人的にラムダアプローチがより明確であると感じています。

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

関連する問題