我正在使用“类模板推导指南”,并尝试递归使用它。但是我无法获取以下代码进行编译

#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>{}}.valueLive 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/

10-13 01:18