This little program ---------------------- #include <numeric> void f () { bool *p, *q; std::accumulate (p, q, 0U); } ---------------------- counts the 'true's in the range [p,q) but this doesn't work in parallel mode, the compiler says that it can't resolve a function call. It should as per 26.4.1. In particular, the error message is this: 4.3.0/parallel/par_loop.h: In function 'Op __gnu_parallel::for_each_template_random_access_ed(RandomAccessIterator, RandomAccessIterator, Op, Fu&, Red, Result, Result&, typename std::iterator_traits<_Iterator>::difference_type) [with RandomAccessIterator = bool*, Op = __gnu_parallel::nothing, Fu = __gnu_parallel::accumulate_selector<bool*>, Red = __gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned int]': 4.3.0/parallel/for_each.h:73: instantiated from 'UserOp __gnu_parallel::for_each_template_random_access(InputIterator, InputIterator, UserOp, Functionality&, Red, Result, Result&, typename std::iterator_traits<_Iterator>::difference_type, __gnu_parallel::parallelism) [with InputIterator = bool*, UserOp = __gnu_parallel::nothing, Functionality = __gnu_parallel::accumulate_selector<bool*>, Red = __gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned int]' 4.3.0/parallel/numeric:103: instantiated from 'T std::__parallel::accumulate_switch(_RAIter, _RAIter, T, _BinaryOper, std::random_access_iterator_tag, __gnu_parallel::parallelism) [with _RAIter = bool*, T = unsigned int, _BinaryOper = std::plus<bool>]' 4.3.0/parallel/numeric:83: instantiated from 'T std::__parallel::accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism) [with _IIter = bool*, T = unsigned int]' x.cc:4: instantiated from here 4.3.0/parallel/par_loop.h:103: error: no match for call to '(__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >) (unsigned int&, bool)' 4.3.0/parallel/omp_loop.h: In function 'Op __gnu_parallel::for_each_template_random_access_omp_loop(RandomAccessIterator, RandomAccessIterator, Op, Fu&, Red, Result, Result&, typename std::iterator_traits<_Iterator>::difference_type) [with RandomAccessIterator = bool*, Op = __gnu_parallel::nothing, Fu = __gnu_parallel::accumulate_selector<bool*>, Red = __gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned int]': 4.3.0/parallel/for_each.h:75: instantiated from 'UserOp __gnu_parallel::for_each_template_random_access(InputIterator, InputIterator, UserOp, Functionality&, Red, Result, Result&, typename std::iterator_traits<_Iterator>::difference_type, __gnu_parallel::parallelism) [with InputIterator = bool*, UserOp = __gnu_parallel::nothing, Functionality = __gnu_parallel::accumulate_selector<bool*>, Red = __gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned int]' 4.3.0/parallel/numeric:103: instantiated from 'T std::__parallel::accumulate_switch(_RAIter, _RAIter, T, _BinaryOper, std::random_access_iterator_tag, __gnu_parallel::parallelism) [with _RAIter = bool*, T = unsigned int, _BinaryOper = std::plus<bool>]' 4.3.0/parallel/numeric:83: instantiated from 'T std::__parallel::accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism) [with _IIter = bool*, T = unsigned int]' x.cc:4: instantiated from here 4.3.0/parallel/omp_loop.h:78: error: no match for call to '(__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >) (unsigned int&, bool)' 4.3.0/parallel/omp_loop.h:86: error: no match for call to '(__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >) (unsigned int&, bool)' 4.3.0/parallel/workstealing.h: In function 'Op __gnu_parallel::for_each_template_random_access_workstealing(RandomAccessIterator, RandomAccessIterator, Op, Fu&, Red, Result, Result&, typename std::iterator_traits<_Iterator>::difference_type) [with RandomAccessIterator = bool*, Op = __gnu_parallel::nothing, Fu = __gnu_parallel::accumulate_selector<bool*>, Red = __gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned int]': 4.3.0/parallel/for_each.h:79: instantiated from 'UserOp __gnu_parallel::for_each_template_random_access(InputIterator, InputIterator, UserOp, Functionality&, Red, Result, Result&, typename std::iterator_traits<_Iterator>::difference_type, __gnu_parallel::parallelism) [with InputIterator = bool*, UserOp = __gnu_parallel::nothing, Functionality = __gnu_parallel::accumulate_selector<bool*>, Red = __gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned int]' 4.3.0/parallel/numeric:103: instantiated from 'T std::__parallel::accumulate_switch(_RAIter, _RAIter, T, _BinaryOper, std::random_access_iterator_tag, __gnu_parallel::parallelism) [with _RAIter = bool*, T = unsigned int, _BinaryOper = std::plus<bool>]' 4.3.0/parallel/numeric:83: instantiated from 'T std::__parallel::accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism) [with _IIter = bool*, T = unsigned int]' x.cc:4: instantiated from here 4.3.0/parallel/workstealing.h:204: error: no match for call to '(__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >) (unsigned int&, bool)' While 26.4.1 doesn't spell this out explicitly, one can only deduce that what is mean is that the accumulator variable has the same type as the initializer, which in the example is 'unsigned int'. Consequently, the function should do something like while (p!=q) acc += *p++; in which case the rhs is converted to int. The current implementation attempts to use an accumulator of type 'bool'. W.
Instead of std::plus, a functor should be used that accepts two different types for LHS and RHS, Result and std::iterator_traits<RandomAccessIterator>::value_type, respectively.
As I've said in the other report, I believe you shouldn't rely on the existence of iterator_traits for the iterator type. You should use the return type of dereferencing the iterator. W.
Wolfgang, I think some of this is fixed, and for the rest (comment #2), there is another bug report (33490) that is focused just on that. Is my understanding correct? -benjamin
(In reply to comment #3) > Wolfgang, I think some of this is fixed, and for the rest (comment #2), there > is another bug report (33490) that is focused just on that. > > Is my understanding correct? I believe so. In any case, by adding a few std:: to my call (which works around PR 33486) I can now build my code. I'll see if it also works... Thanks for your prompt work on all this! Best W.
I meant to close this one, as it appears fixed.