https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111535
Bug ID: 111535 Summary: _RangeAdaptorClosure's (range | adaptor) operator is underconstrained Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: hewillk at gmail dot com Target Milestone: --- // range | adaptor is equivalent to adaptor(range). template<typename _Self, typename _Range> requires __is_range_adaptor_closure<_Self> && __adaptor_invocable<_Self, _Range> constexpr auto operator|(_Range&& __r, _Self&& __self) { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); } The pipe operator here does not constrain the Range template parameter, but the range adaptor closure object requires arguments to model the range. This makes libstdc++ accept the following #include <ranges> struct closure : std::ranges::range_adaptor_closure<closure> { int operator()(int); }; int main() { auto r = 42 | closure{}; } https://godbolt.org/z/hj9a68ssT