https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66153
--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Reduced further: #include <type_traits> template <class T> struct TypeMapper { static const int NestLevel = T::NestLevel; }; template<> struct TypeMapper<double> { static const int NestLevel = 0; }; template<class obj> struct Container { obj data; }; template<class obj> struct Recursive { enum { NestLevel = TypeMapper<obj>::NestLevel + 1}; }; template<int N,class obj, typename std::enable_if<N==obj::NestLevel >::type * = nullptr > auto function(const obj &arg)-> obj { return arg; } template<int N,class obj, typename std::enable_if<N!=obj::NestLevel >::type * = nullptr > auto function(const obj &arg)-> obj { return obj{}; } template<int N,class obj> auto function(const Container<obj> & arg) -> Container<decltype(function<N>(arg.data))> { Container<Recursive<Recursive<double> > > ret; return ret; } int main(int argc,char **argv) { Container<Recursive<Recursive<double> > > array; Container<Recursive<Recursive<double> > > ret; function<1>(array); } ----- CUT ----- I have seen another one similar to this recently.