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.

Reply via email to