在 C++ 中编译时计算并打印阶乘;

发布于 2024-10-17 11:30:20 字数 417 浏览 1 评论 0原文

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。

谢谢!

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;
}

above program computes factorial value during compile time. I want to print factorial value at compile time rather than at runtime using cout. How can we achive printing the factorial value at compile time?

I am using VS2009.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

四叶草在未来唯美盛开 2024-10-24 11:30:20

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

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

错误消息:

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

这里 362880010 的阶乘。

在 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
阶乘 = 120]'
:main.cpp:16:39:此处需要
main.cpp:13:48:警告:隐式常量转换中溢出
[-Woverflow] struct _{ 运算符 char() { 返回阶乘 + 256; } };
//总是溢出

这里 1205 的阶乘。

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;
}

看起来很棒

The factorial can be printed in compiler-generated message as:

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

Error message:

prog.cpp:14:32: error: aggregate ‘_<3628800> __’ has incomplete type and cannot be defined
_::value> __;
^

Here 3628800 is factorial of 10.

See it at ideone : http://ideone.com/094SJz

So are you looking for this?


EDIT:

Matthieu asked for a clever trick to both print the factorial AND let the compilation continue. Here is one attempt. It doesn't give any error, hence the compilation succeeds with one warning.

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

It gets compiled with this warning:

main.cpp: In instantiation of '_::operator char() [with int
factorial = 120]'
: main.cpp:16:39: required from here
main.cpp:13:48: warning: overflow in implicit constant conversion
[-Woverflow] struct _{ operator char() { return factorial + 256; } };
//always overflow

Here 120 is factorial of 5.

Demo at ideone : http://coliru.stacked-crooked.com/a/c4d703a670060545

You could just write a nice macro, and use it instead as:

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

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

That looks great.

南巷近海 2024-10-24 11:30:20

我正在学习 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

i am learning basics of TMP, and want to know the result at compile to make sure logic is correct.

In that case, what you really want is a static assertion:

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

If your compiler does not support static_assert yet, you can use BOOST_STATIC_ASSERT.

叹梦 2024-10-24 11:30:20

我确信现在已经太晚了,但仍然如此。

// 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;

I am sure it is far too late, but still.

// 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;
青衫儰鉨ミ守葔 2024-10-24 11:30:20

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

[[填充]]

There is definitely no standard way. I can't think of a compiler-specific way, either.

[[Filler]]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文