8 Declarators [dcl.decl]

8.3 Meaning of declarators [dcl.meaning]

8.3.2 References [dcl.ref]

In a declaration T D where D has either of the forms

& attribute-specifier-seqopt D1
&& attribute-specifier-seqopt D1

and the type of the identifier in the declaration T D1 is β€œ derived-declarator-type-list T,” then the type of the identifier of D is β€œ derived-declarator-type-list reference to T.” The optional attribute-specifier-seq appertains to the reference type. Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.simple]), in which case the cv-qualifiers are ignored. [ Example:

typedef int& A;
const A aref = 3;   // ill-formed; lvalue reference to non-const initialized with rvalue

The type of aref is β€œlvalue reference to int”, not β€œlvalue reference to const int”.  β€” end example ] Note: A reference can be thought of as a name of an object.  β€” end note ] A declarator that specifies the type β€œreference to cv void” is ill-formed.

A reference type that is declared using & is called an lvalue reference, and a reference type that is declared using && is called an rvalue reference. Lvalue references and rvalue references are distinct types. Except where explicitly noted, they are semantically equivalent and commonly referred to as references.

Example:

void f(double& a) { a += 3.14; }
// ...
double d = 0;
f(d);

declares a to be a reference parameter of f so the call f(d) will add 3.14 to d.

int v[20];
// ...
int& g(int i) { return v[i]; }
// ...
g(3) = 7;

declares the function g() to return a reference to an integer so g(3)=7 will assign 7 to the fourth element of the array v. For another example,

struct link {
  link* next;
};

link* first;

void h(link*& p) {  // p is a reference to pointer
  p->next = first;
  first = p;
  p = 0;
}

void k() {
   link* q = new link;
   h(q);
}

declares p to be a reference to a pointer to link so h(q) will leave q with the value zero. See also [dcl.init.ref].  β€” end example ]

It is unspecified whether or not a reference requires storage ([basic.stc]).

There shall be no references to references, no arrays of references, and no pointers to references. The declaration of a reference shall contain an initializer ([dcl.init.ref]) except when the declaration contains an explicit extern specifier ([dcl.stc]), is a class member ([class.mem]) declaration within a class definition, or is the declaration of a parameter or a return type ([dcl.fct]); see [basic.def]. A reference shall be initialized to refer to a valid object or function. [ Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the β€œobject” obtained by indirection through a null pointer, which causes undefined behavior. As described in [class.bit], a reference cannot be bound directly to a bit-field.  β€” end note ]

If a typedef-name ([dcl.typedef], [temp.param]) or a decltype-specifier ([dcl.type.simple]) denotes a type TR that is a reference to a type T, an attempt to create the type β€œlvalue reference to cv TR” creates the type β€œlvalue reference to T”, while an attempt to create the type β€œrvalue reference to cv TR” creates the type TR. [ Example:

int i;
typedef int& LRI;
typedef int&& RRI;

LRI& r1 = i;                    // r1 has the type int&
const LRI& r2 = i;              // r2 has the type int&
const LRI&& r3 = i;             // r3 has the type int&

RRI& r4 = i;                    // r4 has the type int&
RRI&& r5 = 5;                   // r5 has the type int&&

decltype(r2)& r6 = i;           // r6 has the type int&
decltype(r2)&& r7 = i;          // r7 has the type int&

 β€” end example ]

Note: Forming a reference to function type is ill-formed if the function type has cv-qualifiers or a ref-qualifier; see [dcl.fct].  β€” end note ]