无限模板实例化
Infinite template instantiation
这是我简化的测试代码:
struct Test {
Test() { run(0); }
template<class T>
static auto run(T&&, bool stop = false) -> void { if (!stop) _run<T>(); }
template<class R>
static auto _run() -> void { [] () { run([] () {}, true); }(); }
};
当我使用 GCC 和 clang 编译此代码时,它给出了编译错误:
/media/data/caca3d/src/b0util/test/tst_promise.cpp:30: error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
static auto _run() -> void { [] () { run([] () {}, true); }(); }
~~~^~~~~~~~~~~~~~~~
我不明白为什么这段代码会导致无限的模板实例化。
仅供参考,如果我删除_run()
函数中的template<class R>
,错误就消失了。
我在尝试使用 lambda 函数进行一些延迟计算时发现了此错误,因此我无法删除 lambda 中的间接调用。如何解决此问题?
让我们仔细看看发生了什么。第一个函数显式调用_run()
的模板化版本,我想你对这部分没有疑问。
template<class T>
static auto run(T&&, bool stop = false) -> void { if (!stop) _run<T>(); }
第二个更有趣。看起来它只会实例化一次(因为你只是用 lambda 调用run()
一次),但根据标准,每个 lambda 都有自己独特的类型,所以每次实例化 _run()
时,它都会强制创建一个新版本的run()
(因为T
是从函数的参数类型推导出来的), 创建一个无限循环。
template<class R>
static auto _run() -> void { [] () { run([] () {}, true); }(); }
在此特定示例中解决此问题的最简单方法是run()
采用与您的 lambda 匹配的特定(可能与模板参数相关)类型的std::function
。
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 无限模板实例化
- 无限递归模板实例化使用clang时GCC工作正常
- 可变参数模板实例化中的无限递归,试图构建任意深度的树状结构