8.6 — L-value references to const

In the previous lesson (8.5 -- L-value references), we discussed how l-value references can only bind to a modifiable l-value. This means the following is illegal:

But what if we want to have a reference to a non-modifiable l-value?

L-value reference to a const value

We can tell an l-value reference to treat the object it is referencing as const by using the const keyword when declaring the reference. This makes the l-value reference an l-value reference to a const value (sometimes called a reference to const or a const reference).

L-value references to const can bind to non-modifiable l-values:

Because l-value references to const treat their values as const, they can not be used to modify the value being referenced:

Initializing l-value reference to const with a modifiable l-value

L-value references to const can also bind to modifiable l-values:

When a lvalue reference to a const value binds to a modifiable l-value, the value is treated as const when accessed through the reference, even though the underlying value is non-const. For this reason (as shown in the program above), we can modify the value of x through x (which is non-const), but not through ref (which treats the value as const).

Initializing reference to const with r-value

Perhaps surprisingly, l-values references to const can also bind to r-values.

When this happens, an temporary object is created and initialized with the r-value, and the reference is set to point to that temporary object.

An temporary object (also sometimes called an anonymous object or unnamed object) is an object that has no name. Temporary objects have no scope at all (this makes sense, since scope is a property of an identifier, and temporary objects have no name). This means a temporary object can only be used when it is created, since there is no way to refer to it beyond that point.

References to r-values extend the lifetime of the referenced value

Normally, temporary objects are destroyed at the end of the expression in which they are created.

Consider what would happen in the above example if the temporary object created to hold r-value 5 was destroyed at the end of the expression that initializes ref. Reference ref would be left danging (referencing an object that had been destroyed), and we’d get undefined behavior when we tried to print the value of ref.

To avoid dangling references in such cases, C++ has a special rule: When a reference to a const value is initialized with an r-value, the lifetime of the r-value is extended to match the lifetime of the reference.

Key insight

L-value references can only bind to modifiable l-values.

However, l-value references to const can bind to both modifiable and non-modifiable l-values, as well as r-values. This makes them much more flexible.

8.7 -- Pass by reference and return by reference
8.5 -- L-value references

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">