https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100249
Bug ID: 100249 Summary: missing forwarding std::__invoke result in ranges::is_permutation and ranges::clamp Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: hewillk at gmail dot com Target Milestone: --- Hey, in ranges::is_permutation in ranges_algo.h#L808: auto __proj_scan = std::__invoke(__proj1, *__scan); auto __comp_scan = [&] <typename _Tp> (_Tp&& __arg) { return std::__invoke(__pred, __proj_scan, std::forward<_Tp>(__arg)); }; the __proj_scan seems to forget to use auto&& to receive the std::__ invoke call, which will cause compile failure if the return type is non-copyable: https://godbolt.org/z/WaKc7bWM4 also, we should perfect forward the type of __proj_scan to the next std::__invoke call, and ranges::clamp in ranges_algo.h#L3232 has the same issue: auto&& __proj_val = std::__invoke(__proj, __val); if (std::__invoke(__comp, __proj_val, std::__invoke(__proj, __lo))) return __lo; when the type of __proj_val is an rvalue reference, we need to convert it to rvalue for the next std::__invoke call: https://godbolt.org/z/1G7aqxs3c. So I think it should be relatively safe to inline all std::__invoke calls.