The constexpr specifier (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.
The C++11 standard introduces a new keyword constexpr as a declaration specifier. You can apply the constexpr specifier only to the following contexts:
  • The definition of a variable
  • The declaration of a function or function template
  • The declaration of a static data member
For example:
constexpr int i = 1;     // OK, definition
constexpr int f1();      // OK, function declaration, but must be defined before use
If you declare a function that is not a constructor with a constexpr specifier, that function is a constexpr function. Similarly, if you declare a constructor with a constexpr specifier, that constructor is a constexpr constructor. Both constexpr functions and constexpr constructors are implicitly inline. For example:
struct S {
  constexpr S(int i) : mem(i) { }  // OK, declaration of a constexpr constructor
  private:
    int mem;
};
constexpr S s(55);  // OK, invocation of a constexpr constructor
If any declaration of a function or function template is specified with constexpr, all its declarations must contain the constexpr specifier. For example:
constexpr int f1();  // OK, function declaration
int f1() {           // Error, the constexpr specifier is missing
  return 55;
}     
Function parameters cannot be declared with the constexpr specifier. The following example demonstrates this:
constexpt int f4(constexpr int);  //Error
A constexpr specifier used in an object declaration declares the object as const. Such an object must be of a literal type and initialized. If it is initialized by a constructor call, that call must be a constant expression. Otherwise, if a constexpr specifier is used in a reference declaration, every full expression that appears in its initializer must be a constant expression. Each implicit conversion used in converting the initializer expressions and each constructor call used for the initialization must be valid in a constant expression. For example:
constexpr int var;       // Error, var is not initialized
constexpr int var1 = 1;  // OK

void func() {
  var1 = 5;  //Error, var1 is const
}

struct L {
  constexpr L() : mem(55) { }
  constexpr L(double d) : mem((int)d) { }
  L(int i) : mem(i) { }
  operator int() { return mem; }
private:
  int mem;
};

// Error, initializer involves a non-constexpr constructor.
constexpr L var2(55);   

double var3 = 55;

// Error, initializer involves a constexpr constructor with non-constant argument
constexpr L var4(var3);   

// Error, involves conversion that uses a non-constexpr conversion function
constexpr int var5 = L();  
A constexpr specifier for a nonstatic member function that is not a constructor declares that member function to be const. The class of that constexpr member function must be a literal type. In the following example, the class NL is a non-literal type because it has a user-provided destructor.
struct NL {
  constexpr int f(){       //error, enclosing class is not a literal type
     return 55;
  }       
  ~NL() { }
};

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

The main function cannot be declared with the constexpr specifier.