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 a 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!