The introduction of constexpr in C++11 [2.1.4 ] greatly simplified some compile-time complex computations, even though they were some limitations. The most frustrating of which was certainly the constraint that constexpr functions should contain a single statement (a return statement). In practice this means no variable, no branch or control flow other than the ternary ?: operator and using recursion for any loop-based algorithm. See for example this implementation of popcount() we wrote in section [2.1.4 ]:
#include<cstdio>
constexpr int popcount(unsigned n)
{
return (n == 0) ? 0 : ((n & 1) + popcount(n >> 1));
}
int main(int argc, char**)
{
int array[popcount(45)];
printf("%d' n", popcount(argc));
return 0;
}
In C++14, these restrictions are lifted and we can implement this function in a less convoluted way3:
#include<cstdio>
constexpr int popcount(unsigned n)
{
int result = 0;
for (; n != 0; n >>= 1)
if ((n & 1) != 0)
++result;
return result;
}
int main(int argc, char**)
{
int array[popcount(45)];
printf("%d' n", popcount(argc));
return 0;
}
struct s
{
int value;
constexpr int increment(int v)
{
// Can’t do that in C++11 as the function signature is actually
//
// constexpr int increment(int) const.
//
// Okay in C++14, where the function signature is as declared.
return value += v;
}
};
A subtle change in the transition from C++11 to C++14 is that constexpr used on a member function does not implies const anymore. For example, this code would not compile in C++11 but does in C++14:
This can come as a surprise when switching to a newer standard since calling a constexpr-only member function on a const instance will suddenly trigger errors like “passing ‘const x’ as ‘this’ argument discards qualifiers”.
3Not that recursion is inherently convoluted. Some algorithms work very well when implemented in a recursive way, both regarding the readability and the performance, but even though any programmer worth is money must be know the practice I would argue that most code, i.e. the code we are familiar with, is non-recursive.