template instantiation depth exceeds maximum – how to stop particular case?

I have a following function:

template<unsigned fromLine, unsigned toLine = fromLine>
void stateChanged()
{
    // onStateChangeHandler[fromLine]();

    if (fromLine < toLine)
        stateChanged<fromLine + 1, toLine>();
}

which I call it in a following way:

stateChanged<0>();
stateChanged<1>();
stateChanged<2>();
stateChanged<3>();
stateChanged<4>();
stateChanged<5, 9>();
stateChanged<10, 15>();

I am receiving fatal error: template instantiation depth exceeds maximum of 900. I assumed in C++14 the if condition will stop it automatically. So, how to do this properly?

Answer

Without the ability to use if constexpr in the template definition, you need to change how you do the looping in order to introduce a way for the compiler to reach a terminal state and stop the template instantiation.

We can do this with a helper class that, rather than going from start to finish, processes a number of lines.

template <unsigned curLine, unsigned numLines>
void updateStateChanged()
{
    // onStateChangeHandler[curLine]();
    stateChanged<curLine + 1, numLines - 1>();
}

template <unsigned curLine>
void updateStateChanged<curLine, 0>()
{
    // onStateChangeHandler[curLine]();
}

// Then we can modify your original class to call this helper:

template<unsigned fromLine, unsigned toLine = fromLine>
void stateChanged()
{
    updateStateChanged(fromLine, toLine - fromLine);
}

Leave a Reply

Your email address will not be published. Required fields are marked *