C ++中的递归结构

时间:2013-01-04 03:14:25

标签: c++

我找到了以下代码,它似乎有效,但我根本无法理解 它看起来像 Recursive Struct ,但我以前从未见过它。

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;

任何想法是什么?

2 个答案:

答案 0 :(得分:3)

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

阅读您最喜欢的c ++教科书中的模板

如果您还没有c ++教科书:您需要它,请查看SO常见问题 C++ book list


更好的(在几年内)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;
}

然而,visual c ++ 11.0不支持,这是我写的最新版本的visual c ++

答案 1 :(得分:2)

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

  • 模板参数是,而不是模板中人们通常所期望的类型;
  • 结构模板的字段value是根据这些参数计算的;
  • 当使用N设置时,模板对第二个参数0具有部分特化。

正如您所注意到的,模板会在value字段计算中递归。如果未定义部分特化,那么递归将是无限的。当第二个参数“到达”0时,即。当通过遵循模板实例化的嵌套来获取计算最外层所需的连续值字段时,编译器最终需要实例化参数N等于0的模板,并选择部分特化版本,包含该字段的常量值1。然后编译器可以计算每个嵌套值字段,最终返回到最外面的字段。

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

但这种方法的问题,看起来多么聪明,是它的可读性,因此易于维护。这很可能是新标准提供constexpr概念的原因,这是定义所谓的pure computation的一种非常恰当的方式。


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