how to initialize a constexpr reference

  1. Are constexpr references ever useful? (i.e., "better" than const references)

They are guaranteed to be initiailized before the program starts, whereas a reference to const can be initialized during dynamic initialization, after the program starts running.

  1. If yes, how can I effectively define them?

A constexpr reference has to bind to a global, not a local variable (or more formally, it has to bind to something with static storage duration).

A reference is conceptually equivalent to taking the address of the variable, and the address of a local variable is not a constant (even in main which can only be called once and so its local variables are only initialized once).


So the problem is that a constexpr reference needs to bind to an object with static storage duration, which is covered in the draft C++11 standard: N3337 section 5.19 [expr.const] (emphasis mine):

A reference constant expression is an lvalue core constant expression that designates an object with static storage duration or a function

The draft C++14 standard: N3936 changes the wording:

A constant expression is either a glvalue core constant expression whose value refers to an object with static storage duration or to a function, or a prvalue core constant expression whose value is an object where, for that object and its subobjects:

  • each non-static data member of reference type refers to an object with static storage duration or to a function, and
  • if the object or subobject is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object (5.7), the address of a function, or a null pointer value.

So changing the declaration of x like so would work:

constexpr static int x{20};

Like T.C. says, the initializer needs to be an object with static storage duration.

N4140/§5.19/4 A constant expression is either a glvalue core constant expression whose value refers to an object with static storage duration [...]

N4140/§7.1.5/9 A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. [...] Otherwise, or if a constexpr specifier is used in a reference declaration, every full-expression that appears in its initializer shall be a constant expression.

In N3337, the wording is different.