26
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!

Nawaz
  • 353,942
  • 115
  • 666
  • 851
venkysmarty
  • 11,099
  • 25
  • 101
  • 184
  • Why do simple things in a complicated way? If you just need your factorial calculated, compose a usual program (without TMP), compile and run it. – Vlad Feb 12 '11 at 11:15
  • 4
    i am learning basics of TMP, and want to know the result at compile to make sure logic is correct – venkysmarty Feb 12 '11 at 11:19
  • @user: TMP is basically a way of computing constants at compile time. In which form would you expect the output to be done? In preprocessor it's too early (the constants are calculated later), at the "usual" compilation step you can only output using `cout` and the like (which require to _run_ the program). – Vlad Feb 12 '11 at 11:29

4 Answers4

36

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.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 4
    Good answer, but you shouldn't use reserved symbols (`_` and `__`). – Mike Seymour Feb 12 '11 at 11:37
  • @Mike: I used these symbols so as to make them less visible. But I agree! – Nawaz Feb 12 '11 at 11:41
  • 4
    The purpose of the code is to cause an error. Don't think that the reserved names thing applies here. – Puppy Feb 12 '11 at 11:46
  • 1
    Oh wow, this certainly *is* a way to print something during compile time. :) Nice misuse of the compiler, +1. – Xeo Feb 12 '11 at 11:52
  • 1
    @Nawaz: nice :) Do you know a clever trick to both print the result during compilation AND let the compilation continue ? – Matthieu M. Feb 12 '11 at 17:33
  • @DeadMG: well, a "smartass" compiler could decide to throw an error because of `__` and not issue the error you are interested in so it does apply, but since this is only demo code, I'd vote to preserve it as is, let those who wish it alter their own copy. – Matthieu M. Feb 12 '11 at 17:35
  • @Matthieu: Please see my attempt. I'm able to do that. :-) – Nawaz Feb 12 '11 at 19:15
  • @Matthieu and @Mike: Please see my edit. Now it prints factorial as warning message, rather than error message. :-) – Nawaz Feb 13 '11 at 05:40
  • 1
    @Nawaz: That's clever :) What's more the `_` could indeed be used to print about any result... as long as it's positive to make sure it overflows :) – Matthieu M. Feb 13 '11 at 10:09
  • @Matthieu: Exactly. As long as the template integral argument is non-negative, it will overflow. :-) – Nawaz Feb 13 '11 at 10:14
  • The `_` and `__` really messed up the readability of the code – frankliuao Jul 03 '17 at 20:28
8

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.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • 1
    Wrong. In more complicated cases (like when I want to print-out a complex type deduced by compiler) I may not know exact answer, or even just be lazy to type it in. – ulidtko Nov 07 '11 at 05:48
4

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;
Siborgium
  • 356
  • 4
  • 6
0

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

[[Filler]]

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • I am not even sure there is a way actually. All the `#pragma message` or `#warning` I can think of would typically print the line, not the result of the computation :/ – Matthieu M. Feb 12 '11 at 11:20