Skip to main content
An lvalue reference is an alias for an existing object or function designated by an lvalue expression—an expression category that determines the identity of an entity. Once initialized, it acts as a direct syntactic substitute for the bound entity. Any valid operations performed on the reference—such as assignment for modifiable objects or the address-of operation for objects and functions—are evaluated directly on the original aliased entity. An lvalue reference cannot bind directly to a bit-field; if a const lvalue reference is initialized from a bit-field, it binds to a materialized temporary copy of the bit-field’s value rather than the bit-field itself.

Syntax

An lvalue reference is declared using the ampersand (&) declarator modifier following the type.

Core Mechanics

1. Mandatory Initialization An lvalue reference must be initialized to bind to a valid target upon creation. While this typically requires an initializer at the point of declaration, exceptions exist where the initialization is deferred or handled by the calling context:
  • extern reference declarations.
  • Function parameters (e.g., void foo(int& x);).
  • Function return types (e.g., int& bar();).
  • Non-static reference data members initialized in a constructor’s member initializer list (though since C++11, they may also be initialized directly at the point of declaration using default member initializers).
2. Non-Reseatable Once an lvalue reference is bound to an entity, it cannot be re-bound to a different entity. Any subsequent assignment operations mutate the value of the originally bound object, rather than changing what the reference aliases.
3. Object Identity In the C++ object model, a reference is not guaranteed to occupy storage and does not possess a distinct memory address accessible via standard C++. Applying the address-of operator (&) to an lvalue reference yields the address of the bound object or function.

Binding Rules

The rules governing what an lvalue reference can bind to depend strictly on its const-qualification. Non-Const Lvalue References (T&)
  • Can bind to modifiable lvalues of type T (or a type derived from T).
  • Can bind to objects of unrelated class types, provided the class has a user-defined implicit conversion operator that returns an lvalue reference to T (e.g., operator T&()).
  • Cannot bind to const lvalues.
  • Cannot bind to rvalues (prvalues or xvalues), such as literals or temporary objects returned by value.
Const Lvalue References (const T&)
  • Can bind to modifiable lvalues.
  • Can bind to const lvalues.
  • Can bind to rvalues. When a const lvalue reference binds to a temporary object (prvalue), C++ generally invokes lifetime extension, extending the temporary’s lifetime to match the scope of the reference. However, this extension does not apply in certain contexts, such as when a temporary is bound to a reference member in a constructor’s member initializer list, or when a temporary is bound to a reference returned by a function. In those cases, the temporary is destroyed at the end of the full-expression, leaving a dangling reference.

Dangling References

Because an lvalue reference is merely an alias, it does not manage the lifetime of the entity it binds to (except in the specific, limited case of const T& lifetime extension). If the bound object is destroyed or goes out of scope before the reference, the reference becomes “dangling.” Accessing a dangling reference results in undefined behavior.
Tired of Poor C++ Skills? Fix That With Deep Grasping!Learn More