Calculating and printing factorial at compile time in C++

前端 未结 4 788
逝去的感伤
逝去的感伤 2020-12-01 12:34
template
struct Factorial {
    enum { value = n * Factorial::value};
};

template<>
struct Factorial<0> {
    enum {val         


        
相关标签:
4条回答
  • 2020-12-01 12:44

    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.

    0 讨论(0)
  • 2020-12-01 12:57

    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.

    0 讨论(0)
  • 2020-12-01 12:59

    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;
    
    0 讨论(0)
  • 2020-12-01 13:01

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

    [[Filler]]

    0 讨论(0)
提交回复
热议问题