https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100396
--- Comment #4 from vopl at bk dot ru --- I understand what you're saying. But, apparently, there is still corruption in the calculus of the substituted Args, please look at this code (thanks to johny5): /////////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...); } 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([](double){}, 2.); } ----------------------- <source>: In instantiation of 'struct Checker<use()::<lambda(double)>, double, double>': <source>:8:25: required by substitution of 'template<class F, class ... Args> auto ovr(F, Args ...) requires valid<F, Args ...> [with F = use()::<lambda(double)>; Args = {double, double}]' <source>:14:27: required from 'auto ovr(F, Args ...) requires valid<F, Args ...> [with F = use()::<lambda(double)>; Args = {double}]' <source>:25:8: required from here <source>:4:30: error: no match for call to '(use()::<lambda(double)>) (double, double)' 4 | using Some = decltype(F{}(Args{}...)); | ~~~^~~~~~~~~~~ <source>:4:30: note: candidate: 'void (*)(double)' (conversion) <source>:4:30: note: candidate expects 2 arguments, 3 provided <source>:25:9: note: candidate: 'use()::<lambda(double)>' 25 | ovr([](double){}, 2.); | ^ <source>:25:9: note: candidate expects 1 argument, 2 provided Take attention at 'Args' - it was {double} initially, but becomes {double, double} for second ovr call