Doing a recursion experiment with templates, I've come up with this:
#include <iostream>
#include <utility>
template< int INDEX = 0 >
void constexpr callInTuple( int index ) {
if( INDEX == index ) {
std::cout << INDEX << '\n';
} else {
std::cout << "Intentando con " << INDEX << ", fallido\n";
callInTuple< INDEX + 1 >( index );
}
}
int main( ) {
callInTuple( 1 );
return 0;
}
What I expect, when calling the function with the literal argument 1
, is that something like this will be displayed on the screen:
Trying 0, failed
1
But it doesn't even compile, showing the error in the title:
template instantiation depth exceeds maximum ...
If I try it by calling the function like
callInTuple( 0 );
I would expect an even shorter output, like so:
0
However, I get the exact same error .
What am I doing wrong ?
How do I solve it ?
Let's play at being the compiler.
Templates are instantiated at compile time when they substitute received arguments. Let's do it: We know that
callInTuple
no parameter template is instantiated with0
, so we must replace all of themINDEX
with0
, so the generated function is:The work is not finished, there is another call to
callInTuple
with the expression0 + 1
that at compile time is translated to1
, so we must replace all theINDEX
by1
, therefore the generated function is:But we are not done, now it is instantiated
callInTuple
with the expression2
, so we must replace all theINDEX
by2
:When you have repeated this about 65,535 times (this number can vary depending on the compiler or compiler parameters:
-ftemplate-depth
) the compiler will give up.This means that you've done the recursion wrong: it never reaches the base case . You get the same error because it
index
is a variable at run time while itINDEX
is known at compile time and the compiler has no choice but to keep generating instances ofcallInTuple
because it has no means to break recursion at compile time.Your problems are:
if constexpr
.Proposal .
But this solution uses the C++17 static conditional, since the question is tagged as C++11 you can't use it, so you should do a specialization of the template... but you can't partially specialize template functions:
So the solution will go through specializing classes:The above code produces the following output :