Calculating and printing factorial at compile time in C++
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!
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.
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
.
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;
There is definitely no standard way. I can't think of a compiler-specific way, either.
[[Filler]]
精彩评论