https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119888
--- Comment #10 from Patrick Palka <ppalka at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #8) > (In reply to Andrew Pinski from comment #5) > > And r15-3091-g51761c50f843d5 . > > Patrick, please take a look. I think the above commit caused this change in > behaviour, which doesn't seem conforming to me. > > std::projected<I, Proj>::value_type should still be valid after P2609R3, but > now it doesn't work if I is not a class type, or just doesn't define a > nested value_type. Darn, that's unfortunate, because the optimization is a natural one that provides a few % compile time speedup when using ranges algorithms. The result of std::projected seems overspecified to provide value_type and difference_type members instead of just specifying what iter_value_t / iter_difference_t of the result should give. I never got around to opening an LWG issue for that. We could constrain the optimization to types that already provide ::value_type, but we'd also have to consider the conditionally present ::difference_type, which seems not worth the complexity. I think we should just revert r15-3091 on the 15 branch? A workaround in user code in the meantime is to use std::iter_value_t<std::projected<...>> instead of std::projected<...>::value_type, and same with std::iter_difference_t vs ::difference_type.