c++ - 有没有办法递归使用类模板参数推导指南?(图灵完备)
问题描述
我正在使用 Class Template Deduction Guide 并尝试递归使用它。但我无法获得以下代码进行编译
#include <type_traits>
template<int N>
using int_const = std::integral_constant<int,N>;
template<int N>
struct Foo{
constexpr static int value = N;
template<int C>
constexpr Foo(int_const<C>){};
};
Foo(int_const<0>) -> Foo<1>;
template<int N>
Foo(int_const<N>) -> Foo<N*(Foo{int_const<N-1>{}}.value)>;
int main(){
return Foo{int_const<5>{}}.value;
}
这是错误:
<source>: In substitution of 'template<int N> Foo(int_const<N>)-> Foo<(N * > Foo{std::integral_constant<int, (N - 1)>{}}.value)> [with int N = -894]': <source>:17:51: recursively required by substitution of 'template<int N> Foo(int_const<N>)-> Foo<(N * Foo{std::integral_constant<int, (N - 1)>{}}.value)> [with int N = 4]' <source>:17:51: required by substitution of 'template<int N> Foo(int_const<N>)-> Foo<(N * Foo{std::integral_constant<int, (N - 1)>{}}.value)> [with int N = 5]' <source>:20:30: required from here <source>:17:1: fatal error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) Foo(int_const<N>) -> Foo<N*(Foo{int_const<N-1>{}}.value)>; ^~~
编译终止。
解决方案
您需要一个帮助模板:
template<int N>
struct foo_helper
{ static constexpr int value = N * Foo{int_const<N-1>{}}.value; };
template<>
struct foo_helper<0>
{ static constexpr int value = 1; };
有了这个(也是唯一的)扣除指南:
template<int C>
Foo(int_const<C>)
-> Foo<foo_helper<C>::value>
;
Foo{int_const<5>{}}.value
正确评估为 120 的现场演示。
为什么会这样?
因为有了下面的扣分指南
template<int N>
Foo(int_const<N>) -> Foo<N*(Foo{int_const<N-1>{}}.value)>;
当 CTAD 启动时,会考虑所有指南;即使您提供了更专业的指南 ( Foo<0>
),此递归指南也明确专门化并Foo{int_const<N-1>{}}
最终专门用于N=0
,因此是无限递归。
间接层的引入foo_helper
打破了这种无限递归:您可以专门化一个类,而不是演绎指南。
推荐阅读
- r - 安装的 R github 包不包含 R/sysdata.Rda
- javascript - 如何根据另一个复杂对象属性过滤复杂对象
- java - 如何编写 JMS 代理?
- oauth-2.0 - 在不泄露应用密钥的情况下将桌面应用连接到 Google 相册
- python - Python:JSON 数据到 Pandas,嵌套列表理解
- c# - 如何在可滚动的 xaml 中制作固定位置按钮
- node.js - 分叉子进程的问题是杀死父进程而不显示错误
- java - java.sql.SQLException:没有找到适合 jbdc:mysql://localhost:3306/loginDB & java.lang.NullPointerException 的驱动程序
- reactjs - 确定 Redux 状态空数组是初始状态还是返回空数组的 API 调用的结果的推荐方法是什么?
- c++ - 在 C++ 中解析数据包数据的最佳方法是什么?