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
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
The
constexpr specifier
has no effect on the type of a constexpr function
or 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); //ErrorA
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.