C++11 introduced a more generalized framework to write constant expressions, extending to regular functions and user-defined objects. This removed many of the limitations in previous versions but still there were limits on the structure of a function in order for it to be suitable to become constexpr
.
One of the biggest limitations was the fact that constant-expression functions could only have a body consisting of a single return <expr>
statement, where <expr>
is a constant expression itself, and a very limited syntax. This was (is) necessary in order to avoid side effects outside of the function that could lead to errors or inefficiencies, such as memory allocations/deallocations, templating, exceptions, lambdas, etc. For example, the following constexpr functions are illegal in C++11
constexpr int f(int x) // error: x=(x+1) not a const-expression
{
return x++;
}
constexpr int f2(int x) // error: body of f2() not a return statement
{
int y = 5;
return x+y;
}
constexpr int f3(int x) // error: body of f3() not a return statement
{
if(x>0)
return 5;
else
return 0;
}
constexpr int f4(int x) // error: body of f4() not a return statement
{
for(int i=0; i<5; i++){
x = i * i + x;
}
return x;
}
C++14 has relaxed these constraints so that it is now possible to use a richer syntax. Specifically, local variables, if
statements and loops are now allowed. The above code compiles now perfectly in C++14
int y = f(1); // =1
int y2 = f2(1); // =6
int y3 = f3(1); // =5
int y4 = f4(1); // =31
Great!