2017-04-13 20 views
0

オブジェクトの1つをC++11標準を使用して複数のスレッドに渡そうとしています。出力ストリームオブジェクトと他の引数を複数のスレッドに渡す

ofstreamオブジェクトを渡したいのは、すべてのスレッドが別の出力ファイルに書き込むようにしたいからです。

私はこのようにスレッドと出力ストリームを初期化しています:

std::thread execution_threads[NUMBER_OF_THREADS]; // creating multiple empty threads 
std::ofstream output_files[NUMBER_OF_THREADS]; // Empty output streams 
// Opening and initializing the output files 

各スレッドは、2つの引数を取る関数実行:

void execution(int thread_id, std::ofstream& output_file) 

をだから私は周りを見回していると私は」関数funcに複数の引数がある場合は、を使用する必要はなく、std::thread t(func, a,b,c,d);と書くだけで渡すことができます。a,b,c,dの場合は、C++11を読んでください。だから私は、スレッドを起動するために、このループを書いた:

for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) { 
    execution_threads[i] = std::thread(execution, i, output_files[i]); 
} 

事は、このコードは、このエラーでコンパイルできないということである。

Call to implicitly-deleted copy constructor of 
'typename decay<basic_ofstream<char, char_traits<char> > &>::type' 
(aka 'std::__1::basic_ofstream<char, std::__1::char_traits<char> >') 

私はこの中で、入力としてstructを使用している場合ながら方法はすべて正常に動作します。

このようにして、すべてが正常に動作し、コンパイルされ、完全に動作します。しかし、私は実際には、コンパイラが、私が他のメソッドを使用する場合、私は削除されたコピーコンストラクタを使用しようとしていると私に伝えている理由を知りません。

ありがとうございました。

答えて

2

std::threadは、その引数のコピーを格納します。 std::ofstreamのようなコピーできないオブジェクトを渡すと文句を言います。

あなたは2つのオプションがあります。

1)std::ofstreamオブジェクトの配列を格納しないでください。スレッドに自分のストリームを保存させるだけです。この場合、ストリーム(罰金であるだけで動く、)をコピーする必要はありません。もちろん

for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) { 
    execution_threads[i] = std::thread(execution, i, std::ofstream{}); 
                //^^^^^^^^^^^^^^^ anonymous temporary 
} 

が、この場合には、あなただけのスレッドが独自のストリームを構築するかもしれない(多分ちょうどに渡しますファイル名)。

2)std::reference_wrapper<std::ofstream>をスレッドに渡します。 std::reference_wrapper<T>は、Tへの参照を保持し、T&への暗黙的な変換を持つオブジェクトであるため、ストリーム自体ではなく参照のコピーが終了します。あなたはTを推測し、入力を減らすためにstd::ref工場を使用することができます(すべてのstd::reference_wrapperは結局のところ、それはだ)

for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) { 
    execution_threads[i] = std::thread(execution, i, std::ref(output_files[i])); 
                //^^^^^^^^ std::ref added 
} 

これは持っているでしょうstd::ofstream&を含む構造体を渡すと同じ所有権と寿命の問題のすべてであなたを残しますが、 。すべてのスレッドが完了するまで、output_files配列が存続することを確認するのはあなた次第です。

関連する問題