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 ([dcl.typedef]) or of a template type argument ([temp.arg]), 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 dereferencing 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 ([dcl.typedef]), a type template-parameter ([temp.arg.type]), 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 ]