https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112490
Patrick Palka <ppalka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ppalka at gcc dot gnu.org Status|UNCONFIRMED |NEW Ever confirmed|0 |1 Last reconfirmed| |2025-02-26 --- Comment #5 from Patrick Palka <ppalka at gcc dot gnu.org> --- (In reply to Barry Revzin from comment #3) > In this case, we're comparing two objects of type > wrapped<basic_const_iterator<int*>> with <, so we should have two candidates: > > 1. wrapped's <=>, which has no constraints > 2. basic_const_iterator<int*>'s friend operator<, which we start > instantiating with _It=int* and _It2=wrapped<basic_const_iterator<int*>>. > > (2) requires checking if _It and _It2 can be ordered, which I think > recursively instantiates itself. > > Assuming that's correct (hopefully?), I think CWG 2369 should actually cause > this to be accepted - since wrapped<basic_const_iterator<int*>> is not > convertible to basic_const_iterator<int*>, that should cause (2) to be > rejected before we even consider constraints since it's not viable. It's the other way around after CWG 2369 -- constraints must be checked checked _before_ non-dependent conversions. > > I have no idea what the public-ness of the member changes. Ah, that's because GCC 14 relaxed the CWG 2369 change for non-dependent conversions to/from an aggregate class, which we can safely check (and efficiently recognize) before checking constraints since doing so won't induce any template instantiations (and so won't change the semantics of valid code but will let us accept more code that's invalid after CWG 2369). Making the member public turns basic_const_iterator into an aggregate class, triggering the shortcut.