and the type of the contained declarator-id in the declaration
TD1
is “derived-declarator-type-listT”,
the type of the declarator-id in
D
is “derived-declarator-type-list reference to
T”.
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.
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].
Attempting to bind a reference to a function where
the converted initializer is a glvalue whose
type is not call-compatible ([expr.call])
with the type of the function's definition
results in undefined behavior.
Attempting to bind a reference to an object where
the converted initializer is a glvalue through which
the object is not type-accessible ([basic.lval])
results in undefined behavior.
The object designated by such a glvalue can be
outside its lifetime ([basic.life]).
Because a null pointer value or a pointer past the end of an object
does not point to an object,
a reference in a well-defined program cannot refer to such things;
see [expr.unary.op].
As described in [class.bit], a reference cannot be bound directly
to a bit-field.
— end note]
The behavior of an evaluation of a reference ([expr.prim.id], [expr.ref]) that
does not happen after ([intro.races]) the initialization of the reference
is undefined.
[Example 3: int&f(int&);
int&g();
externint&ir3;
int*ip =0;
int&ir1 =*ip; / undefined behavior: null pointerint&ir2 = f(ir3); / undefined behavior: ir3 not yet initializedint&ir3 = g();
int&ir4 = f(ir4); / undefined behavior: ir4 used in its own initializerchar x alignas(int);
int&ir5 =*reinterpret_cast<int*>(&x); / undefined behavior: initializer refers to char object — end example]
If a typedef-name ([dcl.typedef], [temp.param])
or a decltype-specifier ([dcl.type.decltype]) denotes a type TR that
is a reference to a type T, an attempt to create the type “lvalue reference to cvTR”
creates the type “lvalue reference to T”, while an attempt to create
the type “rvalue reference to cvTR” creates the type TR.
[Example 4: int i;
typedefint& LRI;
typedefint& 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]