https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125981
--- Comment #6 from Ян Чуркин <yanchurkin at gmail dot com> --- (In reply to Jonathan Wakely from comment #2) > I don't think this is a bug. The standard requires that the predicate's > result type is boolean-testable, which means: > > "given two types T1 and T2 that each model boolean-testable-impl , the && > and || operators within the expressions declval<T1>() && declval<T2>() and > declval<T1>() || declval<T2>() resolve to the corresponding built-in > operators." Thanks, that's helpful background. Agreed - P1964 / P2167 (LWG 2114) and [concept.booleantestable] are all formalising the same "the logical operators must resolve to the built-ins" intent, and this fix is squarely in that spirit. One thing worth noting for this PR: the predicate's result type actually does pass the syntactic boolean-testable check -- it is convertible to bool and !t is too. What defeats it is the namespace-scope operator&&(bool, T): in 'first != last && pred(*first)' the right operand has class type, so that ADL-found operator&& is an exact match and is preferred over the built-in (which would need the user-defined conversion on the second operand). That is exactly the failure mode the [concept.booleantestable] note warns about, and the concept itself cannot prevent such an overload from existing. So regardless of whether one considers such a type strictly conforming input, the robust thing -- and what libstdc++ already does in lower_bound, search_n, etc. -- is to force the operand to bool so the built-in && is used. The patch just makes __find_if, __mismatch and __push_heap consistent with that. No behavioural change for well-behaved predicates; the ranges:: versions are already fine via their bool-returning wrappers.
