我正在使用“类模板推导指南”,并尝试递归使用它。但是我无法获取以下代码进行编译
#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;
}
这是错误:
编译终止。
最佳答案
您需要一个帮助器模板:
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
的Live demo正确评估为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
的引入打破了这种无限递归:您可以专门设计一个类,而不是推论指南。关于c++ - 有没有一种方法可以递归使用“类模板参数推导指南”? (图灵完成了吗),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54195113/