能否在编译时计算数字的阶乘,但不使用枚举?

8

我希望能够在编译时计算阶乘。我已经找到了一些解决方案,但我想知道是否有其他方法来解决这个问题,而不使用enum。以下是使用enum的解决方案。

#include <iostream>
template <int n>
struct fact
{
    enum{value = n*fact<n-1>::value};
};

template<>
struct fact<1>
{
    enum{value = 1};
};

int main()
{
    std::cout << fact<10>::value;
}

如果没有其他解决方案,请说明为什么必须使用enum


请查看维基百科上的模板元编程页面:http://zh.wikipedia.org/wiki/模板元编程。其中包含一个示例:http://zh.wikipedia.org/wiki/模板元编程#在编译期生成类。 - sehe
3个回答

11

尽管有其他的符号表示法,但是使用枚举式符号是因为更多的编译器接受该表示法。该语言支持带有内联初始化的const整数类型类成员,但一些编译器在这方面不符合标准。在符合标准的编译器上,以下代码可以正常工作:

#include <iostream>
template <unsigned int n>
struct fact
{   
    static const unsigned int value = n*fact<n-1>::value;
};  

template<>
struct fact<0>
{   
    static const unsigned int value = 1;
};  

int main()
{   
    std::cout << fact<10>::value << "\n";
}   

fact<0> 可能应该作为基本情况(0!= 1) - Adam Bowen
相同的解决方案可以在http://en.wikipedia.org/wiki/Template_metaprogramming找到。 - sehe
维基百科文章中的解决方案使用了枚举版本。这里并不一定要使用枚举。 - David Hammen
@Adam:你说得对:fact<0> 应该是基准情况。我只是采用了原帖作者的代码,并且摆脱了枚举类型。 - David Hammen

7

替换操作,

enum{value};

使用,

static int const value; // or unsigned int
enum是必需的,因为它们应该在编译时解决。这确保了您计算的任何结果都必须在编译时完成。另一种类似的类型是static int const(表示任何整数类型)。
举个例子:
enum E {
 X = strlen(s); // is an error, because X is a compile time constant
};

这里并不一定需要枚举。该语言允许为静态整数类型的const成员赋初值。只有在不兼容的编译器上(显然很常见)才必须使用枚举。 - David Hammen
@iammilind 感谢你的回答。我想知道为什么必须写成 static int const,而 static int 不可接受。 - Samvel Hovsepyan
@Samvel,因为static int在编译时无法解析;因此即使您这样做,它也不会是一个编译时常量。 - iammilind

7

或者,您可以使用静态常量成员:

template <unsigned int n>
struct fact { static const unsigned int value = n * fact<n-1>::value; }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接