25
template<unsigned int n>
struct Factorial {
    enum { value = n * Factorial<n-1>::value};
};

template<>
struct Factorial<0> {
    enum {value = 1};
};

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

上面的程序在编译期间计算阶乘值。我想在编译时而不是在运行时使用 cout 打印阶乘值。我们如何在编译时打印阶乘值?

我正在使用VS2009。

谢谢!

4

4 回答 4

35

阶乘可以在编译器生成的消息中打印为:

template<int x> struct _;
int main() {
        _<Factorial<10>::value> __;
        return 0;
}

错误信息:

prog.cpp:14:32:错误:聚合 '_<3628800> __' 类型不完整,无法定义 _::value> __; ^

这里3628800是 的阶乘10

在 ideone 看到它:http: //ideone.com/094SJz

那你在找这个吗?


编辑:

Matthieu 要求一个聪明的技巧来打印阶乘并让编译继续。这是一种尝试。它没有给出任何错误,因此编译成功并发出一个警告。

template<int factorial> 
struct _{ operator char() { return factorial + 256; } }; //always overflow
int main() {
        char(_<Factorial<5>::value>());
        return 0;
}

它编译时带有以下警告:

main.cpp:在 '_::operator char() [with int factorial = 120]' 的实例化中:main.cpp:16:39:从这里需要 main.cpp:13:48:警告:隐式常量转换溢出[-Woverflow] struct _{ operator char() { return factorial + 256; } }; //总是溢出

这里120是 的阶乘5

ideone 演示:http ://coliru.stacked-crooked.com/a/c4d703a670060545

您可以只编写一个不错的宏,然后将其用作:

#define PRINT_AS_WARNING(constant) char(_<constant>())    

int main() 
{
         PRINT_AS_WARNING(Factorial<5>::value);
         return 0;
}

看起来很棒。

于 2011-02-12T11:34:48.857 回答
8

我正在学习 TMP 的基础知识,并想知道编译时的结果以确保逻辑正确。

在这种情况下,你真正想要的是一个静态断言:

static_assert(Factorial<5> ::value ==     120,  "5! should be 120");
static_assert(Factorial<10>::value == 3628800, "10! should be 3628800");

如果您的编译器还不支持static_assert,您可以使用BOOST_STATIC_ASSERT.

于 2011-02-12T11:38:26.517 回答
4

我相信现在为时已晚,但仍然如此。

// definition
template<typename T, T N>
struct print_constexpr{
    [[deprecated]]
    print_constexpr(){ }
};

// usage
print_constexpr<unsigned int, Factorial<5>::value> x;

// output
{path to file}: warning: ‘print_constexpr<T, N>::print_constexpr() [with T = unsigned int; T N = 120]’ is deprecated [-Wdeprecated-declarations]
    print_constexpr<unsigned int, Factorial<5>::value> x;
于 2019-02-25T13:21:01.290 回答
0

绝对没有标准的方法。我也想不出特定于编译器的方式。

[[填料]]

于 2011-02-12T11:12:47.530 回答