#include <iostream>
constexprdouble nth(double x, int n) // assume 0<=n
{
double res = 1;
int i = 0;
while (i<n) {
res*=x;
++i;
}
return res;
}
int main()
{
std::cout << nth(2, 5);
return 0;
}
since the function is defined using constexpr and the values of the parameters are clear for the compiler (2, 5) before entering into run-time, then the output is given at compile-time, hence we may have a little performance enhancement compared to the time we omit the keyword constexpr. Right?
Your latest code snippet gives a compilation error because nth(n, d) can't be evaluated at compile-time.
Marking the function constexpr might influence the compiler's choice to evaluate/optimize the function at compile time but it's not a guarantee unless you call it from a constexpr context (e.g. when using the function return value to initialize a constexpr variable, specify the size of static array or to use as a template argument; or when calling the function from another constexpr function that has been called from such a constexpr context).
This will evaluate at compile time - as static_assert returns true:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include <iostream>
constexprdouble nth(double x, unsigned n) {
double res {x};
if (x > 1)
for (unsigned i {}; i < n - 1; ++i)
res *= x;
return res;
}
int main() {
static_assert (nth(2, 5) == 32);
}
However, if the values of the args for nth can't be determined at compile time, then it will be evaluated at run-time
Since C++20 there is also consteval which will cause an error if the function cannot produce a compile-time evaluation (ie an error if can only be evaluated at run-time).
It provides a way to reliably guarantee static initialization and compile-time evaluation without relying on the (implementation-dependent, unreliable) compiler optimizer.
const alone doesn't do this. If the initializer for a const variable is not a constant expression, the compiler will fall back to dynamic initialization. Depending on the initializer, the process of dynamic initialization can require arbitrary amounts of time and space.
It is desirable to have a guarantee that such expensive processes are not performed at run-time, and this guarantee is what constexpr offers.