https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100396
--- Comment #3 from Patrick Palka <ppalka at gcc dot gnu.org> --- (In reply to vopl from comment #2) > Please, try this, also failed > > /////////0/////////1/////////2/////////3/////////4/////////5/////////6/////// > //7 > template<class F, class... Args> struct Checker > { > using Some = decltype(F{}(Args{}...)); > }; > > template<class F, class... Args> concept valid = > requires { typename Checker<F, Args...>::Some; }; > > /////////0/////////1/////////2/////////3/////////4/////////5/////////6/////// > //7 > template<class F, class... Args> auto ovr(F f, Args... args) > requires valid<F, Args...> > { > return ovr<F, Args...>(int{}, f, args...); // a second ovr is expected > to be called, but the compiler tries to call this ovr again. Collision > between 'int' and 'F' is ignored, extra Args provided to call > } > > template<class F, class... Args> auto ovr(int, F f, Args... args) > { > return f(args...); > } > > /////////0/////////1/////////2/////////3/////////4/////////5/////////6/////// > //7 > void use() > { > ovr([]{}); > } > > > $ g++-11.1.0 -std=c++20 -c src.cpp > src.cpp: In instantiation of 'struct Checker<use()::<lambda()>, > use()::<lambda()> >': > src.cpp:8:25: required by substitution of 'template<class F, class ... > Args> auto ovr(F, Args ...) requires valid<F, Args ...> [with F = > use()::<lambda()>; Args = {use()::<lambda()>}]' > src.cpp:14:27: required from 'auto ovr(F, Args ...) requires valid<F, > Args ...> [with F = use()::<lambda()>; Args = {}]' > src.cpp:25:8: required from here > src.cpp:4:30: error: no match for call to '(use()::<lambda()>) > (use()::<lambda()>)' > 4 | using Some = decltype(F{}(Args{}...)); > | ~~~^~~~~~~~~~~ > src.cpp:4:30: note: candidate: 'void (*)()' (conversion) > src.cpp:4:30: note: candidate expects 1 argument, 2 provided > src.cpp:25:9: note: candidate: 'use()::<lambda()>' > 25 | ovr([]{}); > | ^ > src.cpp:25:9: note: candidate expects 0 arguments, 1 provided > > ---------- > IMHO, the problem is not caused by concepts, but caused by corrupted > overloading selection mechanic. Please, take a look at the collision between > argument 'int{}' and first template parameter specified as 'F'. Next, no > SFINAE expected in this case due to correct overloading, but overloading > failed and SFINAE happens. Thanks. Although the collision between 'int{}' and the template argument for 'F' does mean that the first overload ultimately isn't viable, the compiler as per CWG2369 first needs to check the overload's constraints (using the provided/deduced template arguments) _before_ checking whether 'int' is convertible to 'F', and it's during this constraint checking we hit the hard error. So as far as I can tell, the compiler is behaving as specified. See also PR99599 and its related PRs.