でいくつかの機能をテストしているstd::thread
ときに、友人が GCC で問題に遭遇しました。これが GCC のバグなのか、それともこのコードに何か問題があるのか を尋ねる価値があると考えました (コードは (たとえば) "7 8 9 10 1 2 3" を出力します)。 、しかし、[1,10] のすべての整数が出力されることを期待しています):
#include <algorithm>
#include <iostream>
#include <iterator>
#include <thread>
int main() {
int arr[10];
std::iota(std::begin(arr), std::end(arr), 1);
using itr_t = decltype(std::begin(arr));
// the function that will display each element
auto f = [] (itr_t first, itr_t last) {
while (first != last) std::cout<<*(first++)<<' ';};
// we have 3 threads so we need to figure out the ranges for each thread to show
int increment = std::distance(std::begin(arr), std::end(arr)) / 3;
auto first = std::begin(arr);
auto to = first + increment;
auto last = std::end(arr);
std::thread threads[3] = {
std::thread{f, first, to},
std::thread{f, (first = to), (to += increment)},
std::thread{f, (first = to), last} // go to last here to account for odd array sizes
};
for (auto&& t : threads) t.join();
}
次の代替コードが機能します。
int main()
{
std::array<int, 10> a;
std::iota(a.begin(), a.end(), 1);
using iter_t = std::array<int, 10>::iterator;
auto dist = std::distance( a.begin(), a.end() )/3;
auto first = a.begin(), to = first + dist, last = a.end();
std::function<void(iter_t, iter_t)> f =
[]( iter_t first, iter_t last ) {
while ( first != last ) { std::cout << *(first++) << ' '; }
};
std::thread threads[] {
std::thread { f, first, to },
std::thread { f, to, to + dist },
std::thread { f, to + dist, last }
};
std::for_each(
std::begin(threads),std::end(threads),
std::mem_fn(&std::thread::join));
return 0;
}
関数のアリティの順序付けられていない評価と関係があるか、修飾されていない引数std::thread
をコピーするときに機能するはずの方法であると考えました。std::ref
次に、最初のコードを Clang でテストしたところ、動作しました (そのため、GCC のバグが疑われ始めました)。
使用コンパイラ: GCC 4.7、Clang 3.2.1
編集: GCC コードは、コードの最初のバージョンでは間違った出力を提供しますが、2 番目のバージョンでは正しい出力を提供します。