web-dev-qa-db-ja.com

オブジェクト参照引数をスレッド関数に渡すとコンパイルに失敗するのはなぜですか?

新しいc ++ 11 std::threadインターフェースの使用で問題が発生しました。
スレッドが実行する関数にstd::ostreamへの参照を渡す方法がわかりません。

整数を渡す例を次に示します(gcc 4.6で期待どおりにコンパイルして動作します):

void foo(int &i) {
    /** do something with i **/
    std::cout << i << std::endl;
}

int k = 10;
std::thread t(foo, k);

しかし、ostreamを渡そうとすると、コンパイルされません。

void foo(std::ostream &os) {
    /** do something with os **/
    os << "This should be printed to os" << std::endl;
}

std::thread t(foo, std::cout);

それを行う方法はありますか、それともまったく不可能ですか?

注意:コンパイルエラーから、削除されたコンストラクターから来ているようです...

29
Benjamin A.

スレッドコピー彼らの議論(それについて考えてください、それは正しいことです)。明示的に参照が必要な場合は、std::ref(または定数参照の場合はstd::cref)でラップする必要があります。

std::thread t(foo, std::ref(std::cout));

(参照ラッパーは、参照の周りに値セマンティクスを持つラッパーです。つまり、ラッパーをcopyでき、すべてのコピーに同じ参照が含まれます。 )

いつものように、このコードは、参照するオブジェクトが存続している間だけ正しいです。買い手責任負担。

50
Kerrek SB