[dcl.init.ref]

# 9 Declarations [[dcl]](./#dcl)

## 9.5 Initializers [[dcl.init]](dcl.init#ref)

### 9.5.4 References [dcl.init.ref]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6115)

A variable whose declared type is
âreference to Tâ ([[dcl.ref]](dcl.ref "9.3.4.3 References"))
shall be initialized[.](#1.sentence-1)

[*Example [1](#example-1)*: int g(int) noexcept;void f() {int i; int& r = i; // r refers to i r = 1; // the value of i becomes 1int* p = &r; // p points to iint& rr = r; // rr refers to what r refers to, that is, to iint (&rg)(int) = g; // rg refers to the function g rg(i); // calls function gint a[3]; int (&ra)[3] = a; // ra refers to the array a ra[1] = i; // modifies a[1]} â *end example*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6137)

A reference cannot be changed to refer to another object after initialization[.](#2.sentence-1)

[*Note [1](#note-1)*:

Assignment to a reference assigns to the object referred to by the reference ([[expr.assign]](expr.assign "7.6.19 Assignment and compound assignment operators"))[.](#2.sentence-2)

â *end note*]

Argument passing ([[expr.call]](expr.call "7.6.1.3 Function call"))and function value return ([[stmt.return]](stmt.return "8.8.4 The return statement")) are initializations[.](#2.sentence-3)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6148)

The initializer can be omitted for a reference only in a parameter declaration ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")),
in the declaration of a function return type, in the declaration of
a class member within its class definition ([[class.mem]](class.mem "11.4 Class members")), and where theextern specifier is explicitly used[.](#3.sentence-1)

[*Example [2](#example-2)*: int& r1; // error: initializer missingextern int& r2; // OK â *end example*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6162)

Given types â*cv1* T1â and â*cv2* T2â,
â*cv1* T1â is [*reference-related*](#def:reference-related "9.5.4 References [dcl.init.ref]") to
â*cv2* T2â ifT1 is similar ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")) to T2, orT1 is a base class of T2[.](#4.sentence-1)

â*cv1* T1â is [*reference-compatible*](#def:reference-compatible "9.5.4 References [dcl.init.ref]") with â*cv2* T2â if
a prvalue of type âpointer to *cv2* T2â can be converted to
the type âpointer to *cv1* T1â
via a standard conversion sequence ([[conv]](conv "7.3 Standard conversions"))[.](#4.sentence-2)

In all cases where the reference-compatible relationship
of two types is used to establish the validity of a reference binding and
the standard conversion sequence would be ill-formed,
a program that necessitates such a binding is ill-formed[.](#4.sentence-3)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6178)

A reference to type â*cv1* T1â is initialized by
an expression of type â*cv2* T2â as follows:

- [(5.1)](#5.1)

  If the reference is an lvalue reference and the initializer expression
  * [(5.1.1)](#5.1.1)

is an lvalue (but is not a
bit-field), and
â*cv1* T1â is reference-compatible with
â*cv2* T2â, or

  * [(5.1.2)](#5.1.2)

has a class type (i.e.,T2 is a class type), where T1 is not reference-related to T2, and can be converted
to an lvalue of type â*cv3* T3â, where
â*cv1* T1â is reference-compatible with
â*cv3* T3â[80](#footnote-80 "This requires a conversion function ([class.conv.fct]) returning a reference type.") (this conversion is selected by enumerating the applicable conversion
functions ([[over.match.ref]](over.match.ref "12.2.2.7 Initialization by conversion function for direct reference binding")) and choosing the best one through [overload
resolution](over.match "12.2 Overload resolution [over.match]")),

then the reference binds to the initializer expression lvalue in the
first case and to the lvalue result of the conversion
in the second case (or, in either case, to the appropriate base class subobject of the object)[.](#5.1.sentence-1)
  [*Note [2](#note-2)*:
  The usual [lvalue-to-rvalue](conv.lval "7.3.2 Lvalue-to-rvalue conversion [conv.lval]"), [array-to-pointer](conv.array "7.3.3 Array-to-pointer conversion [conv.array]"),
and [function-to-pointer](conv.func "7.3.4 Function-to-pointer conversion [conv.func]") standard
conversions are not needed, and therefore are suppressed, when such
direct bindings to lvalues are done[.](#5.1.sentence-2)
 â *end note*]
  [*Example [3](#example-3)*: double d = 2.0;double& rd = d; // rd refers to dconst double& rcd = d; // rcd refers to dstruct A { };struct B : A { operator int&(); } b;
A& ra = b; // ra refers to A subobject in bconst A& rca = b; // rca refers to A subobject in bint& ir = B(); // ir refers to the result of B​::​operator int& â *end example*]

- [(5.2)](#5.2)

  Otherwise,
if the reference is an lvalue reference to a
type that is not const-qualified or is volatile-qualified,
the program is ill-formed[.](#5.2.sentence-1)
  [*Example [4](#example-4)*: double& rd2 = 2.0; // error: not an lvalue and reference not constint i = 2;double& rd3 = i; // error: type mismatch and reference not const â *end example*]

- [(5.3)](#5.3)

  Otherwise, if the initializer expression
  * [(5.3.1)](#5.3.1)

is an rvalue (but not a bit-field) or an lvalue of function type and
â*cv1* T1â is
reference-compatible with â*cv2* T2â, or

  * [(5.3.2)](#5.3.2)

has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be converted to
an rvalue of type â*cv3* T3â or
an lvalue of function type â*cv3* T3â,
where â*cv1* T1â is
reference-compatible with â*cv3* T3â (see [[over.match.ref]](over.match.ref "12.2.2.7 Initialization by conversion function for direct reference binding")),

then
the initializer expression in the first case and
the converted expression in the second case
is called the converted initializer[.](#5.3.sentence-1)
  If the converted initializer is a prvalue,
let its type be denoted by T4;
the temporary materialization conversion ([[conv.rval]](conv.rval "7.3.5 Temporary materialization conversion")) is applied,
considering the type of the prvalue to be
â*cv1* T4â ([[conv.qual]](conv.qual "7.3.6 Qualification conversions"))[.](#5.3.sentence-2)
  In any case,
the reference binds to the resulting glvalue
(or to an appropriate base class subobject)[.](#5.3.sentence-3)
  [*Example [5](#example-5)*: struct A { };struct B : A { } b;extern B f();const A& rca2 = f(); // binds to the A subobject of the B rvalue. A&& rra = f(); // same as abovestruct X {operator B(); operator int&();} x;const A& r = x; // binds to the A subobject of the result of the conversionint i2 = 42;int&& rri = static_cast<int&&>(i2); // binds directly to i2 B&& rrb = x; // binds directly to the result of operator Bconstexpr int f() {const int &x = 42; const_cast<int &>(x) = 1; // undefined behaviorreturn x;}constexpr int z = f(); // error: not a constant expressiontypedef int *AP[3]; // array of 3 pointer to inttypedef const int *const ACPC[3]; // array of 3 const pointer to const int ACPC &&r = AP{}; // binds directly â *end example*]

- [(5.4)](#5.4)

  Otherwise, T1 shall not be reference-related to T2[.](#5.4.sentence-1)

  * [(5.4.1)](#5.4.1)

      If T1 or T2 is a class type,
user-defined conversions are considered
using the rules for copy-initialization of an object of type
â*cv1* T1â by
user-defined conversion ([[dcl.init]](dcl.init "9.5 Initializers"), [[over.match.copy]](over.match.copy "12.2.2.5 Copy-initialization of class by user-defined conversion"), [[over.match.conv]](over.match.conv "12.2.2.6 Initialization by conversion function"));
the program is ill-formed if the corresponding non-reference
copy-initialization would be ill-formed[.](#5.4.1.sentence-1)
      The result E of the call to the
conversion function, as described for the non-reference
copy-initialization, is then used to direct-initialize the reference
using the form (E)[.](#5.4.1.sentence-2)
      For this direct-initialization, user-defined conversions are not considered[.](#5.4.1.sentence-3)

  * [(5.4.2)](#5.4.2)

      Otherwise,
the initializer expression is implicitly converted to a prvalue
of type âT1â[.](#5.4.2.sentence-1)
      The temporary materialization conversion is applied,
considering the type of the prvalue to be â*cv1* T1â,
and the reference is bound to the result[.](#5.4.2.sentence-2)

  [*Example [6](#example-6)*: struct Banana { };struct Enigma { operator const Banana(); };struct Alaska { operator Banana&(); };void enigmatic() {typedef const Banana ConstBanana;
 Banana &&banana1 = ConstBanana(); // error Banana &&banana2 = Enigma(); // error Banana &&banana3 = Alaska(); // error}const double& rcd2 = 2; // rcd2 refers to temporary with type const double and value 2.0double&& rrd = 2; // rrd refers to temporary with value 2.0const volatile int cvi = 1;const int& r2 = cvi; // error: cv-qualifier droppedstruct A { operator volatile int&(); } a;const int& r3 = a; // error: cv-qualifier dropped// from result of conversion functiondouble d2 = 1.0;double&& rrd2 = d2; // error: initializer is lvalue of reference-related typestruct X { operator int&(); };int&& rri2 = X(); // error: result of conversion function is// lvalue of reference-related typeint i3 = 2;double&& rrd3 = i3; // rrd3 refers to temporary with value 2.0 â *end example*]

In all cases except the last
(i.e., implicitly converting the initializer expression
to the referenced type),
the reference is said to [*bind directly*](#def:bind_directly "9.5.4 References [dcl.init.ref]") to the
initializer expression[.](#5.sentence-2)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6358)

[*Note [3](#note-3)*:

[[class.temporary]](class.temporary "6.8.7 Temporary objects") describes the lifetime of temporaries bound to references[.](#6.sentence-1)

â *end note*]

[80)](#footnote-80)[80)](#footnoteref-80)

This requires a conversion
function ([[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion functions")) returning a reference type[.](#footnote-80.sentence-1)
