模板实例化深度超过最大值 - 如何停止特定情况?
template instantiation depth exceeds maximum - how to stop particular case?
我有以下功能:
template<unsigned fromLine, unsigned toLine = fromLine>
void stateChanged()
{
// onStateChangeHandler[fromLine]();
if (fromLine < toLine)
stateChanged<fromLine + 1, toLine>();
}
我这样称呼它:
stateChanged<0>();
stateChanged<1>();
stateChanged<2>();
stateChanged<3>();
stateChanged<4>();
stateChanged<5, 9>();
stateChanged<10, 15>();
我收到致命错误:模板实例化深度超过最大值 900。
我假设在 C++14 中 if 条件会自动停止它。那么,如何正确地做到这一点?
使用 if constexpr
而不是 if
将防止此代码无限循环。
正如您现在编写的代码,stateChanged
的每个 实例化请求 stateChanged
.
的不同实例化
before [编译器资源管理器]
after [编译器资源管理器]
template<unsigned fromLine, unsigned toLine = fromLine>
void stateChanged()
{
// onStateChangeHandler[fromLine]();
if constexpr(fromLine < toLine)
{
// If the above expression is false, this code is not compiled.
stateChanged<fromLine + 1, toLine>();
}
}
更新:
在 C++14 上,使用一些 SFINAE 可以产生相同的效果。
template<unsigned fromLine, unsigned toLine = fromLine,
typename std::enable_if_t< fromLine>=toLine >* = nullptr >
void stateChanged()
{
// onStateChangeHandler[fromLine]();
}
template<unsigned fromLine, unsigned toLine = fromLine,
typename std::enable_if_t< fromLine<toLine >* = nullptr >
void stateChanged()
{
// onStateChangeHandler[fromLine]();
stateChanged<fromLine + 1, toLine>();
}
C++14 after [编译器资源管理器]
无法在模板定义中使用 if constexpr
,您需要更改循环方式,以便为编译器引入一种方法来达到终止状态并停止模板实例化。
我们可以使用助手 class 来完成此操作,而不是从头到尾处理多行。
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);
}
我有以下功能:
template<unsigned fromLine, unsigned toLine = fromLine>
void stateChanged()
{
// onStateChangeHandler[fromLine]();
if (fromLine < toLine)
stateChanged<fromLine + 1, toLine>();
}
我这样称呼它:
stateChanged<0>();
stateChanged<1>();
stateChanged<2>();
stateChanged<3>();
stateChanged<4>();
stateChanged<5, 9>();
stateChanged<10, 15>();
我收到致命错误:模板实例化深度超过最大值 900。 我假设在 C++14 中 if 条件会自动停止它。那么,如何正确地做到这一点?
使用 if constexpr
而不是 if
将防止此代码无限循环。
正如您现在编写的代码,stateChanged
的每个 实例化请求 stateChanged
.
before [编译器资源管理器]
after [编译器资源管理器]
template<unsigned fromLine, unsigned toLine = fromLine>
void stateChanged()
{
// onStateChangeHandler[fromLine]();
if constexpr(fromLine < toLine)
{
// If the above expression is false, this code is not compiled.
stateChanged<fromLine + 1, toLine>();
}
}
更新:
在 C++14 上,使用一些 SFINAE 可以产生相同的效果。
template<unsigned fromLine, unsigned toLine = fromLine,
typename std::enable_if_t< fromLine>=toLine >* = nullptr >
void stateChanged()
{
// onStateChangeHandler[fromLine]();
}
template<unsigned fromLine, unsigned toLine = fromLine,
typename std::enable_if_t< fromLine<toLine >* = nullptr >
void stateChanged()
{
// onStateChangeHandler[fromLine]();
stateChanged<fromLine + 1, toLine>();
}
C++14 after [编译器资源管理器]
无法在模板定义中使用 if constexpr
,您需要更改循环方式,以便为编译器引入一种方法来达到终止状态并停止模板实例化。
我们可以使用助手 class 来完成此操作,而不是从头到尾处理多行。
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);
}