Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to initialize a constexpr reference

I am trying to initialize a constexpr reference with no success. I tried

#include <iostream>

constexpr int& f(int& x) // can define functions returning constexpr references
{
    return x;
}

int main()
{
    constexpr int x{20};
    constexpr const int& z = x; // error here
}

but I'm getting a compile time error

error: constexpr variable 'z' must be initialized by a constant expression

Dropping the const results in

error: binding of reference to type 'int' to a value of type 'const int' drops qualifiers

even though I had the feeling that constexpr automatically implies const for variable declarations.

So my questions are:

  1. Are constexpr references ever useful? (i.e., "better" than const references)
  2. If yes, how can I effectively define them?

PS: I've seen a couple of questions related to mine, such as Which values can be assigned to a `constexpr` reference? , but I don't think they address my questions.

like image 236
vsoftco Avatar asked Feb 19 '15 18:02

vsoftco


People also ask

Can you modify constexpr?

A const int var can be dynamically set to a value at runtime and once it is set to that value, it can no longer be changed. A constexpr int var cannot be dynamically set at runtime, but rather, at compile time. And once it is set to that value, it can no longer be changed.

Does constexpr need to be static?

A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.

What does constexpr mean in C++?

constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time. A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations.


2 Answers

  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).

like image 73
Jonathan Wakely Avatar answered Sep 30 '22 09:09

Jonathan Wakely


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 image 38
Shafik Yaghmour Avatar answered Sep 30 '22 11:09

Shafik Yaghmour