c++ power of integer, template meta programming

后端 未结 4 1085
抹茶落季
抹茶落季 2020-12-08 17:01

I want to make a function which returns a power of integer. Please read the fmuecke\'s solution in power of an integer in c++ .

However, I want to generalize his so

4条回答
  •  臣服心动
    2020-12-08 17:15

    Solution using recursion:

    #include 
    
    template
    inline constexpr T pow(const T base, unsigned const exponent)
    {
        // (parentheses not required in next line)
        return (exponent == 0) ? 1 : (base * pow(base, exponent-1));
    }
    
    int main()
    {
        std::cout << "pow(2, 4): " << pow(2, 4) << std::endl;
        std::cout << "pow(5, 0): " << pow(5, 0) << std::endl;
    }
    

    Jeremy W. Murphy suggested/requested a version using exponentiation by squaring:

    template
    inline constexpr T pow(const T base, unsigned const exponent)
    {
        // (parentheses not required in next line)
        return (exponent == 0)     ? 1 :
               (exponent % 2 == 0) ? pow(base, exponent/2)*pow(base, exponent/2) :
               base * pow(base, (exponent-1)/2) * pow(base, (exponent-1)/2);
    }
    

    "I heard that it is up to the compiler whether the constexpr function is evaluated in compile time or not."

    True, AFAIK. The compiler isn't required to do constant-initialization at compile-time, but if you use the result of a constexpr function as a non-type template argument, it has to compute the result at compile-time.

    std::cout << std::integral_constant::value << std::endl;
    

    Also see the approach using integral_constant as parameter of pow in Andy Prowl's answer.

    Here's how you can enforce compile-time evaluation:

    #include 
    #include 
    
    // insert a constexpr `pow` implementation, e.g. the one from above
    
    template < typename T, T base, unsigned exponent >
    using pow_ = std::integral_constant < T, pow(base, exponent) >;
    
    // macro == error prone, you have been warned
    #define POW(BASE, EXPONENT) (pow_ < decltype(BASE), BASE, EXPONENT > :: value)
    
    int main()
    {
        std::cout << "pow(2, 4): " << pow_::value << std::endl;
        std::cout << "pow(2, 4): " << POW(2, 4) << std::endl;
    }
    

    Please leave a comment if you downvote so I can improve my answer.

提交回复
热议问题