11 Declarators [dcl.decl]

11.3 Meaning of declarators [dcl.meaning]

11.3.2 References [dcl.ref]

В объявлении, T D где D есть одна из форм

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

и тип идентификатора в объявлении T D1 - «derived-declarator-type-list T», тогда тип идентификатора D - «derived-declarator-type-list ссылка на T». Необязательный параметр attribute-specifier-seqотносится к ссылочному типу. Ссылки с квалификатором cv имеют неправильный формат, за исключением случаев, когда cv-квалификаторы вводятся с использованием символа typedef-name([dcl.typedef], [temp.param]) или decltype-specifier, в этом случае, cv-квалификаторы игнорируются. [Example:

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

Типом aref является «ссылка lvalue на int», а не «ссылка lvalue на const int». ] [ Ссылку можно рассматривать как имя объекта. ] Объявление, указывающее тип «ссылка на », имеет неправильный формат.end exampleNote: end note cv void

Ссылочный тип, объявленный с использованием & , называется lvalue reference, а ссылочный тип, объявленный с использованием && , называется rvalue reference. Ссылки Lvalue и ссылки rvalue - это разные типы. Если явно не указано иное, они семантически эквивалентны и обычно называются ссылками.

[Example:

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

объявляется a ссылочным параметром, f поэтому вызов f(d) будет добавлен 3.14 к d.

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

объявляет функцию g() для возврата ссылки на целое число, поэтому она g(3)=7 будет назначена 7 четвертому элементу массива v. Другой пример:

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);
}

объявляет p ссылку на указатель, link поэтому h(q) оставит q нулевое значение. См. Также [dcl.init.ref]. ]end example

Не указано, требуется ли для ссылки storage ([basic.stc]).

Не должно быть ссылок на ссылки, массивов ссылок и указателей на ссылки. Объявление ссылки должно содержать initializer ([dcl.init.ref]), за исключением случаев, когда объявление содержит явный extern спецификатор ([dcl.stc]), является class member объявлением в определении класса или является объявлением параметра или возвращаемого типа ([dcl.fct]); см [basic.def]. Ссылка должна быть инициализирована для ссылки на действительный объект или функцию. [ В частности, пустая ссылка не может существовать в четко определенной программе, потому что единственный способ создать такую ​​ссылку - это привязать ее к «объекту», полученному косвенным путем через нулевой указатель, что вызывает неопределенное поведение. Как описано в , ссылку нельзя напрямую привязать к битовому полю. ]Note: [class.bit]end note

Если typedef-name([dcl.typedef], [temp.param]) или a decltype-specifierобозначает тип, TR который является ссылкой на тип T, попытка создать тип «ссылка lvalue на cv TR» создает тип «ссылка lvalue на T», в то время как попытка создать тип «ссылка rvalue на cv TR» создает тип TR. [ Note: Это правило известно как сворачивание ссылок. ] [ end noteExample:

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: Формирование ссылки на тип функции неверно, если тип функции имеет cv-qualifiers или ref-qualifier; см [dcl.fct]. ]end note