C++ C+中的递归结构+;

C++ C+中的递归结构+;,c++,C++,我发现了下面的代码,它似乎可以工作,但我根本无法理解它。 它看起来像一个递归结构,但我以前从未见过它 template<int B, int N> struct Pow { enum{ value = B*Pow<B, N-1>::value }; }; template< int B > struct Pow<B, 0> { enum{ value = 1 }; }; int quartic_of_three = Pow<

我发现了下面的代码,它似乎可以工作,但我根本无法理解它。
它看起来像一个递归结构,但我以前从未见过它

template<int B, int N>
struct Pow {
    enum{ value = B*Pow<B, N-1>::value };
};

template< int B >
struct Pow<B, 0> {
    enum{ value = 1 };
};
int quartic_of_three = Pow<3, 4>::value;
模板
结构功率{
枚举{value=B*Pow::value};
};
模板
结构功率{
枚举{值=1};
};
int quartic_of_three=功率::值;

知道这是什么吗?

这是一种在编译时计算整数幂的方法,依靠编译器支持必要数量的模板专门化(即,它不是完全可移植的代码)

<>阅读你喜欢的C++教科书

中的模板

如果你还没有一本C++教科书,你需要它,看一下FAQ <强> <强> < /P>


在C++11中,使用
constexpr
函数是一种更好的(几年后)可能更易于移植的方法:

#include <iostream>
using namespace std;

constexpr int constpow( int base, int n )
{
    return (n == 0? 1 : base*constpow( base, n - 1 ));
}

int main()
{
    int const quarticOfThree = constpow( 3, 4 );
    wcout << quarticOfThree << endl;
}
#包括
使用名称空间std;
constexpr int constpow(int base,int n)
{
返回值(n==0?1:base*constpow(base,n-1));
}
int main()
{
int const quarticOfThree=constpow(3,4);

wcout此模板定义中需要注意的重要事项是:

  • 模板参数是值,而不是许多人通常期望的模板类型
  • 根据这些参数计算结构模板的字段
  • 当设置为
    0
    时,模板对第二个参数
    N
    具有部分专门化
正如您所注意到的,模板在
字段计算上递归。如果未定义部分专门化,则该递归将是无限的。当第二个参数“达到”
0
,即,当通过模板实例化的嵌套尝试获取计算最外层所需的连续值字段时,编译器最终需要实例化参数N等于
0
的模板,并选择包含常量值的部分专门化版本然后编译器可以计算每个嵌套值字段,最终返回到最外层的字段

使用这种技术,可以让编译器离线(即在编译时)计算某些值。这样,程序员就可以通过其参数和公式定义其常量值,而不必硬编码它们,或者让编译后的程序在每次运行时计算它们

但这种方法的问题在于可读性,因此易于维护。这很可能是新标准提供
constepr
概念的原因,这是定义所谓



应该注意的是,模板的两个字段都是有符号的,并且计算不会试图以任何方式处理负值。如果N最初设置为
-1
,结果可能会很有趣。

它使用编译时递归将B计算为N的幂。非常基本的模板元编程-你说的是什么“它不是完全可移植的代码”?我相信它完全符合标准。@Andreitta:你引用了一个结论(这就是“I.e.”的意思)一个句子有一个前提。另一个前提是不同的编译器有不同的限制。因此,这是符合标准的不可移植代码。标准@Andreitta
constexpr
的模板递归深度可能会不合理地缩短,因为此时的可移植性远远低于模板。@Yakk C++03建议至少17,但C++11在将其增加到1024,同时只建议允许至少512个嵌套的
constepr
求值。这有点学术性;唯一真正的规则是为编译器提供一个在合理时间内完成的元程序。编译器有这些限制来打印消息,因此用户不必整天等待结果或g至于法规遵从性,该标准只是没有努力对元程序复杂性进行立法。