Morning! I've got a transform-reduce statement that compiles with execution::seq. When replacing the policy parameter with execution::par, I get a compile time error. This seems odd to me and I'm seeking advice here whether to file a bug report with gcc or not. The environment is a gcc 10.2 on an arch linux derivate; libstdc++ has version 6.0.28 (owned by package gcc-libs 10.2.0-3); libtbb is in use (owned by package tbb 2020.3-1). The statement in questions reads (in a simplified example): Obj x = transform_reduce( execution::par, v.begin(), v.end(), Obj{0}, [](Obj &a,Obj const &b) { a.combine(b); return move(a); }, [](int i){ return Obj{i}; } ); ( overload 6: https://en.cppreference.com/w/cpp/algorithm/transform_reduce ) Pls find the compiler error at the end of this mail; seems to be in the interface to TBB. On the compiler explorer, this behaviour is reproducible, when TBB is selected as additional library. It compiles (and runs) OK there without the TBB. Might this be a bug in gcc's interface to TBB? The complete compiler error messages follows (different name "Inte" for example class). (If requested I can, of course, post a complete source for the problem as well.) Cheers, Kai In file included from /usr/include/c++/10.2.0/pstl/parallel_backend.h:16, from /usr/include/c++/10.2.0/pstl/algorithm_impl.h:22, from /usr/include/c++/10.2.0/pstl/glue_execution_defs.h:50, from /usr/include/c++/10.2.0/execution:32, from ../demos/main.cpp:3: /usr/include/c++/10.2.0/pstl/parallel_backend_tbb.h: In instantiation of ‘void __pstl::__par_backend::__par_trans_red_body<_Index, _Up, _Tp, _Cp, _Rp>::operator()(const tbb::blocked_range<Index>&) [with _Index = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Up = __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >)>; _Tp = Inte; _Cp = main(int, char**)::<lambda(Inte&, const Inte&)>; _Rp = __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte)>]’: /usr/include/tbb/parallel_reduce.h:150:47: required from ‘void tbb::interface9::internal::start_reduce<Range, Body, Partitioner>::run_body(Range&) [with Range = tbb::blocked_range<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >; Body = __pstl::__par_backend::__par_trans_red_body<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >)>, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte)> >; Partitioner = const tbb::auto_partitioner]’ /usr/include/tbb/partitioner.h:423:27: required from ‘void tbb::interface9::internal::dynamic_grainsize_mode<Mode>::work_balance(StartType&, Range&) [with StartType = tbb::interface9::internal::start_reduce<tbb::blocked_range<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >, __pstl::__par_backend::__par_trans_red_body<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >)>, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte)> >, const tbb::auto_partitioner>; Range = tbb::blocked_range<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >; Mode = tbb::interface9::internal::adaptive_mode<tbb::interface9::internal::auto_partition_type>]’ /usr/include/tbb/partitioner.h:256:28: required from ‘void tbb::interface9::internal::partition_type_base<Partition>::execute(StartType&, Range&) [with StartType = tbb::interface9::internal::start_reduce<tbb::blocked_range<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >, __pstl::__par_backend::__par_trans_red_body<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >)>, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte)> >, const tbb::auto_partitioner>; Range = tbb::blocked_range<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >; Partition = tbb::interface9::internal::auto_partition_type]’ /usr/include/tbb/parallel_reduce.h:190:29: required from ‘tbb::task* tbb::interface9::internal::start_reduce<Range, Body, Partitioner>::execute() [with Range = tbb::blocked_range<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >; Body = __pstl::__par_backend::__par_trans_red_body<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >)>, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, __pstl::__internal::__pattern_transform_reduce<const __pstl::execution::v1::parallel_policy&, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte, main(int, char**)::<lambda(Inte&, const Inte&)>, main(int, char**)::<lambda(int)>, std::integral_constant<bool, false> >::<lambda()>::<lambda(__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Inte)> >; Partitioner = const tbb::auto_partitioner]’ /usr/include/tbb/parallel_reduce.h:181:11: required from here /usr/include/c++/10.2.0/pstl/parallel_backend_tbb.h:177:31: error: no match for call to ‘(main(int, char**)::<lambda(Inte&, const Inte&)>) (Inte, Inte)’ 177 | _Tp(_M_combine(_M_u(__i), _M_u(__i + 1))); // The condition i+1 < j is provided by the grain size of 3 | ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/c++/10.2.0/pstl/parallel_backend_tbb.h:177:31: note: candidate: ‘Inte (*)(Inte&, const Inte&)’ (conversion) /usr/include/c++/10.2.0/pstl/parallel_backend_tbb.h:177:31: note: conversion of argument 2 would be ill-formed: /usr/include/c++/10.2.0/pstl/parallel_backend_tbb.h:177:36: error: cannot bind non-const lvalue reference of type ‘Inte&’ to an rvalue of type ‘Inte’ 177 | _Tp(_M_combine(_M_u(__i), _M_u(__i + 1))); // The condition i+1 < j is provided by the grain size of 3 | ~~~~^~~~~ ../demos/main.cpp:41:34: note: candidate: ‘main(int, char**)::<lambda(Inte&, const Inte&)>’ (near match) 41 | [](Inte &a,Inte const &b) /*-> Inte*/ { a.combine(b); return move(a); }, | ^ ../demos/main.cpp:41:34: note: conversion of argument 1 would be ill-formed: In file included from /usr/include/c++/10.2.0/pstl/parallel_backend.h:16, from /usr/include/c++/10.2.0/pstl/algorithm_impl.h:22, from /usr/include/c++/10.2.0/pstl/glue_execution_defs.h:50, from /usr/include/c++/10.2.0/execution:32, from ../demos/main.cpp:3: /usr/include/c++/10.2.0/pstl/parallel_backend_tbb.h:177:36: error: cannot bind non-const lvalue reference of type ‘Inte&’ to an rvalue of type ‘Inte’ 177 | _Tp(_M_combine(_M_u(__i), _M_u(__i + 1))); // The condition i+1 < j is provided by the grain size of 3 | ~~~~^~~~~ -- "They have the ultimate solution to all the problems that we face It's pointing rockets at the russians and hope they don't end up in greece" <Fisher-Z> D-55120 Meenz ++ PGP Key fingerprint 059D 4FAA FE93 5928 1B22 7FAF EC08 5BF9 D50E F933 ++ -----BEGIN GEEK CODE BLOCK----- VERSION: 3.12 GCS/IT d- s: a++>-----(?) C++$ UL++(++++$) P++ L++$ E-(+) W--(+) N !w--- !O !M V? PS+ PE-() Y+ PGP++ t R@* tv--(-) b+>++ DI++ G e+++(*) h? y? ------END GEEK CODE BLOCK------