https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63515
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- The shorter example works in C++17 mode in GCC 7+. It is still rejected in C++11 and C++14 (hitting the assert). clang accepts the shorter example in all modes. ICC rejects it with the assert in all modes. MSVC accepts it in at least C++latest mode (I did not try others). The original example fails in C++17 mode still (and gives the same error message as C++14 mode): <source>: In instantiation of 'struct CurriedImpl<-894, std::function<int(int, int)>, int, int>': <source>:16:8: recursively required from 'struct CurriedImpl<-2, std::function<int(int, int)>, int, int>' <source>:16:8: required from 'struct CurriedImpl<-1, std::function<int(int, int)>, int, int>' /opt/compiler-explorer/gcc-trunk-20210809/include/c++/12.0.0/type_traits:2924:69: required by substitution of 'template<class _Tp, class> static std::true_type std::__is_invocable_impl<std::__invoke_result<CurriedImpl<1, std::function<int(int, int)>, int, int>&, int, int>, int, false, void>::_S_test(int) [with _Tp = int; <template-parameter-1-2> = <missing>]' /opt/compiler-explorer/gcc-trunk-20210809/include/c++/12.0.0/type_traits:2933:42: required from 'struct std::__is_invocable_impl<std::__invoke_result<CurriedImpl<1, std::function<int(int, int)>, int, int>&, int, int>, int, false, void>' /opt/compiler-explorer/gcc-trunk-20210809/include/c++/12.0.0/bits/std_function.h:334:9: required from 'struct std::function<int(int, int)>::_Callable<CurriedImpl<1, std::function<int(int, int)>, int, int>, std::__invoke_result<CurriedImpl<1, std::function<int(int, int)>, int, int>&, int, int> >' /opt/compiler-explorer/gcc-trunk-20210809/include/c++/12.0.0/bits/std_function.h:344:8: required by substitution of 'template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond::value, _Tp>::type [with _Cond = std::function<int(int, int)>::_Callable<CurriedImpl<1, std::function<int(int, int)>, int, int>, std::__invoke_result<CurriedImpl<1, std::function<int(int, int)>, int, int>&, int, int> >; _Tp = void; _Res = int; _ArgTypes = {int, int}]' /opt/compiler-explorer/gcc-trunk-20210809/include/c++/12.0.0/bits/std_function.h:413:9: required by substitution of 'template<class _Functor, class, class> std::function<int(int, int)>::function(_Functor) [with _Functor = CurriedImpl<1, std::function<int(int, int)>, int, int>; <template-parameter-1-2> = void; <template-parameter-1-3> = <missing>]' <source>:25:17: required from 'CurriedImpl<(Depth - 1), F, Args ...> CurriedImpl<Depth, F, Args>::operator()(const First&) [with First = int; int Depth = 1; F = std::function<int(int, int)>; Args = {int, int}]' <source>:49:9: required from here <source>:16:8: fatal error: template instantiation depth exceeds maximum of 900 (use '-ftemplate-depth=' to increase the maximum) 16 | struct CurriedImpl : public CurriedImpl<Depth-1,F,Args...> | ^~~~~~~~~~~ clang accepts it in C++11-C++20 modes. ICC hits assert. MSVC hits the recursiveness.