I'm writing some code which passes lambda functions to a suite of recursive functions. Some of these lambda functions are nested inside other lambda functions. I think I'm writing valid code but I'm getting a fatal error C1060: compiler is out of heap space
error.
Here is a much cut down version of the code
struct Null
{
template <typename SK>
static void match(SK sk)
{
}
};
template <typename T>
struct Repetition
{
template <typename SK>
static void match(SK sk)
{ // <--------------------------------- error message points to this line
T::match([]() { match([]() {}); });
}
};
int main()
{
using Test = Repetition<Null>;
Test::match([](){});
}
Now this minimal version doesn't make much sense but it has the same compiler error. I've indicated the line with the error above.
My question is, is this a compiler bug/limitation or is my code invalid in some way?
Compiler is Visual Studio 2022 compiling C 20.
Thanks
CodePudding user response:
Per [expr.prim.lambda.closure]
The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type
To instantiate Repetition::match
, the compiler must instantiate Null::match
which requires an instantiation of Repetition::match
... and so on. Each time the compiler recurses, []() {}
is treated as a brand new type, ad infinitum.
To get it to stop recursing, replace your call with:
T::match(sk);
CodePudding user response:
While both VS2022 and gcc 11 and 12 just crash on this, clang does manage to give an error message:
<source>:15:25: fatal error: recursive template instantiation exceeded maximum depth of 1024
T::match([]() { match([]() {}); });
^
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: (skipping 1015 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:22:11: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:22:17)>' requested here
Test::match([](){});
^
1 error generated.
ASM generation compiler returned: 1
<source>:15:25: fatal error: recursive template instantiation exceeded maximum depth of 1024
T::match([]() { match([]() {}); });
^
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: (skipping 1015 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:15:25: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:15:31)>' requested here
<source>:22:11: note: in instantiation of function template specialization 'Repetition<Null>::match<(lambda at <source>:22:17)>' requested here
Test::match([](){});
^
1 error generated.
Execution build compiler returned: 1