c++ power of integer, template meta programming -
i want make function returns power of integer. please read fmuecke's solution in power of integer in c++ .
however, want generalize solution arbitrary type t. since c++11 has constexpr, guess possible.
naively, tried like,
template<class t, int n> inline constexpr t pow(const t x){ return pow<n-1>(x) * x; } template<class t> inline constexpr t pow<t, 1>(const t x){ return x; } template<class t> inline constexpr t pow<t, 0>(const t x){ return 1; }
actually approach failed since partial specialization function template not allowed.
and 1 more question. heard compiler whether constexpr function evaluated in compile time or not. how force compute general type. read somewhere 1 of simplest hack integral consts wrap in std::integral_const::value.
solution using recursion:
#include <iostream> template<class t> 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 version using exponentiation squaring:
template<class t> 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 compiler whether constexpr function evaluated in compile time or not."
true, afaik. compiler isn't required constant-initialization @ compile-time, if use result of constexpr function non-type template argument, has compute result @ compile-time.
std::cout << std::integral_constant<int, pow(2, 4)>::value << std::endl;
also see approach using integral_constant
parameter of pow
in andy prowl's answer.
here's how can enforce compile-time evaluation:
#include <iostream> #include <type_traits> // insert constexpr `pow` implementation, e.g. 1 above template < typename t, t base, unsigned exponent > using pow_ = std::integral_constant < t, pow(base, exponent) >; // macro == error prone, have been warned #define pow(base, exponent) (pow_ < decltype(base), base, exponent > :: value) int main() { std::cout << "pow(2, 4): " << pow_<int, 2, 4>::value << std::endl; std::cout << "pow(2, 4): " << pow(2, 4) << std::endl; }
please leave comment if downvote can improve answer.
Comments
Post a Comment