Constexpr functions (C++11)

Note: IBM supports selected features of C++11, known as C++0x before its ratification. IBM will continue to develop and implement the features of this standard. The implementation of the language level is based on IBM's interpretation of the standard. Until IBM's implementation of all the C++11 features is complete, including the support of a new C++11 standard library, the implementation may change from release to release. IBM makes no attempt to maintain compatibility, in source, binary, or listings and other compiler interfaces, with earlier releases of IBM's implementation of the new C++11 features.

A non-constructor function that is declared with a constexpr specifier is a constexpr function. A constexpr function is a function that can be invoked within a constant expression.

A constexpr function must satisfy the following conditions:
  • It is not virtual.
  • Its return type is a literal type.
  • Each of its parameters must be of a literal type.
  • When initializing the return value, each constructor call and implicit conversion is valid in a constant expression.
  • Its function body is = delete or = default; otherwise, its function body must contain only the following statements:
    • null statements
    • static_assert declarations
    • typedef declarations that do not define classes or enumerations
    • using directives
    • using declarations
    • One return statement

When a nonstatic member function that is not a constructor is declared with the constexpr specifier, that member function is constant, and the constexpr specifier has no other effect on the function type. The class of which that function is a member must be a literal type.

The following examples demonstrate the usage of constexpr functions:
const int array_size1 (int x) {
  return x+1;
}
// Error, constant expression required in array declaration
int array[array_size1(10)];    

constexpr int array_size2 (int x) { 
  return x+1; 
} 
// OK, constexpr functions can be evaluated at compile time
// and used in contexts that require constant expressions. 
int array[array_size2(10)];     

struct S {
  S() { }
  constexpr S(int) { }
  constexpr virtual int f() { // Error, f must not be virtual.
    return 55;
  }       
};

struct NL {
  ~NL() { }              // The user-provided destructor (even if it is trivial) 
                         // makes the type a non-literal type.
};

constexpr NL f1() {          // Error, return type of f1 must be a literal type.
  return NL();
}       

constexpr int f2(NL) {       // Error, the parameter type NL is not a literal type.
  return 55; 
}                 

constexpr S f3() {
  return S();
}

enum { val = f3() };         // Error, initialization of the return value in f3()
                             // uses a non-constexpr constructor.

constexpr void f4(int x) {   // Error, return type should not be void.
  return;
}

constexpr int f5(int x) {    // Error, function body contains more than return statement.
  if (x<0)
    x = -x;
  return x;
}
When a function template is declared as a constexpr function, if the instantiation results in a function that does not satisfy the requirements of a constexpr function, the constexpr specifier is ignored. For example:
template <class C> constexpr NL f6(C c) {    // OK, the constexpr specifier ignored
  return NL();
}
void g() {
  f6(55); // OK, not used in a constant expression
}

A call to a constexpr function produces the same result as a call to an equivalent non-constexpr function in all respects, except that a call to a constexpr function can appear in a constant expression.

A constexpr function is implicitly inline.

The main function cannot be declared with the constexpr specifier.