You might be able to use std::pow()
in constexpr
expressions in C++11
Since this post was not tagged "reinventing-the-wheel", I want to point out that some compilers (notably GCC) will compile the below C++11 code:
#include <cmath>
constexpr int ipow(int a, int b) {
return std::pow(a, b);
}
int main(int argc, char *argv[]) {
static_assert(ipow(-5, 3) == -125);
return ipow(argc, 2);
}
One drawback is that std::pow()
converts integer arguments to double
, which at run-time may or may not result in slower computation than using int
. Also, while for int
there is no loss of precision, if you would want to use int64_t
, there is a potential loss of precision.
The other drawback, as pointed out by Oliver Schonrock, is that not all compilers allow constexpr
use of std::pow()
. As explained in this post,
constexpr
math functions were only allowed in C++11 but not in C++14. But there are libraries that provide constexpr
math functions, see for example Sprout's pow()
implementation.
Zero to the power zero is one*
With most programming languages, one usually finds that pow(0, 0) == 1
. You should ensure your solution also returns one in that case, to ensure consistency, regardless of your personal feelings about zero to the power zero.
As a bonus, by having a well-defined result for ipow(0, 0)
, it no longer throws exceptions, and you can get rid of some of the specializations.
Catch exceptions by const reference
Make it a habit to catch exceptions by const reference. Apart from being a little bit faster (although this of course is the least of your worries when exceptions are being thrown), it ensures you don't lose information when the exception thrown is of a derived class. See this StackOverflow question for more information.