Skip to main content
A constexpr member variable is a class-level data member whose value is strictly evaluated and fixed at compile-time. In C++, a constexpr member variable must be declared as static, meaning it belongs to the class itself rather than any specific object instance, and it is implicitly const. C++ prohibits non-static constexpr member variables because a constexpr variable declaration must define a single, globally fixed value associated with the declaration itself. Non-static members, by contrast, represent per-instance state that is initialized by constructors. To achieve compile-time initialization for per-instance data, the correct language mechanism is to declare a standard const member and initialize it via a constexpr constructor.

Syntax and Initialization Rules

  1. In-Class Initialization: The variable must be initialized at the point of declaration inside the class definition.
  2. Constant Expression: The initializer must be a valid constant expression.
  3. Literal Type: The type of the variable must be a literal type. This includes scalar types, references, or class types that possess a constexpr constructor and a constexpr destructor (as of C++20, literal types are no longer required to have a strictly trivial destructor).

Linkage and the One Definition Rule (ODR)

The behavior of static constexpr member variables regarding the One Definition Rule (ODR) changed significantly in C++17.

C++17 and Later (Implicitly Inline)

As of C++17, a static constexpr member variable is implicitly inline. The in-class declaration serves as the complete definition. Even if the variable is ODR-used (e.g., its address is taken or it is bound to a reference), no out-of-line definition is required.

Pre-C++17 (C++11 / C++14)

In older standards, the in-class declaration is only a declaration. If the variable is strictly used as an rvalue (e.g., passing it by value), the compiler substitutes the value directly. However, if the variable is ODR-used, a single out-of-line definition must be provided in exactly one translation unit (.cpp file), without repeating the initializer.

Complex Literal Types

A static constexpr member is not limited to primitive types. It can be a user-defined class type, provided that the class meets the requirements of a literal type.
Tired of Poor C++ Skills? Fix That With Deep Grasping!Learn More