2017-06-22 7 views
0

関数を持つ新しいスレッド(std::thread)を生成すると、その関数の引数 は参考値ではありません。std :: thread arguments(value vs const)

私は参照引数(int& nArg)とその関数を定義するのであれば 私のコンパイラ(mingwの4.9.2)が 「不足しているコピーコンストラクタ」私は;-)

を推測するようcompilian-suaeli何かに(エラーを出力

しかし、私がその参照引数をconst(const int& nArg)にしても、それは文句なしです。

誰か説明できますか?

+10

「compilian-suaeli」と読んで理解できる人もいるので、質問に完全なエラーメッセージを含めてください。 Btwもコードを読むことができるので、[mcve]を追加してください。 – user463035818

+0

私はそれを疑いません。その言葉で私は、原因を見つけるのにあまり役に立たない典型的なコンパイラメッセージを意味しました。 – nji9

+0

エラー出力を英語で入手できるはずです。環境に 'LC_ALL = C'を設定してください。 –

答えて

0

参照を渡す場合はstd::refのおかげでstd::reference_wrapperにラップする必要があります。 Like:

void my_function(int&); 
int my_var = 0; 
std::thread t(&my_function, std::ref(my_var)); 
+0

はい、ありがとう、私は自分自身を見つけました;-)しかし、私は引数をconstにすると、なぜ参照と一緒に動作するのだろうかと思っていました。 – nji9

+0

[スレッド](http://en.cppreference.com/w/cpp/thread/thread/thread)を見てください。*「スレッド関数への引数は値によって移動またはコピーされます」*非** const **参照にバインドすることはできません。 – Jarod42

+0

void my_function(const int&);を実行してもコンパイラに不満はありません。 int my_var = 0; std :: thread t(&my_function、my_var); – nji9

0

std::threadの引数は一度使用されます。

実際には、std::tuple<Ts...> tupに格納します。その後、f(std::get<Is>(std::move(tup))...)を実行します。

std::getの右辺値tupleを渡すことは、タプルの値または右辺参照フィールドから状態を取り出すことが自由であることを意味します。タプルは右辺値ではなく、代わりにそのタプルを参照します。

あなたはreference_wrapper(すなわち、std::ref/std::cref)を使用していない限りstd::tupleで値として、あなたはstd::threadに渡す値はを格納しています。つまり、あなたが呼び出す関数は右辺値をstd::tupleの値に渡します。

の値はconst&にバインドできますが、&にはバインドできません。

上記のstd::tupleは実装の詳細で、std::threadという想像上の実装です。標準の文言は、より鈍いです。


なぜこのようなことが起こるのですか?一般に、&パラメータをすぐに破棄する値にバインドしないでください。この関数は、呼び出し側が見ることができるものを変更していると考えます。値がすぐに破棄されると、これは通常、呼び出し元側のエラーです。一方、パラメータを参照目的だけでなく効率的に使用するため、パラメータは即座に破棄されます。

あるいは、おおよそ、

const int& x = 7; 

は法的

int& x = 7; 

あるためではありません。最初は論理的に破棄されたオブジェクトへのconst&です(これは参照寿命の延長によるものではありませんが、論理的には一時的です)。