Конечно, когда ссылка впервые инициализируется, это делается правильно, удовлетворяя следующим требованиям:
[C++11: 8.3.2/5]:
Не должно быть ссылок на ссылки, массивов ссылок и указателей на ссылки. Объявление ссылки должно содержать инициализатор (8.5.3), за исключением случаев, когда объявление содержит явный спецификатор extern (7.1.1), является объявлением члена класса (9.2) в определении класса или является объявлением параметра или тип возвращаемого значения (8.3.5); см. 3.1. Ссылка должна быть инициализирована для ссылки на действительный объект или функцию. [ Примечание: в частности, нулевая ссылка не может существовать в четко определенной программе, потому что единственный способ создать такую ссылку означало бы привязать ее к «объекту», полученному путем разыменования нулевого указателя, что приводит к неопределенному поведению. Как описано в 9.6, ссылка не может быть привязана непосредственно к битовому полю. —конец примечания ]
Ссылка, возвращаемая функцией, представляет собой xvalue:
[C++11: 3.10/1]:
[..] Значение x (значение «eXpiring») также относится к объекту, обычно близкому к концу его срока службы (например, его ресурсы могут быть перемещены). Значение x является результатом определенных видов выражений, включающих ссылки на значение r (8.3.2). [ Пример: Результатом вызова функции, тип возвращаемого значения которой является ссылка rvalue, является значение xvalue. —конец примера ] [..]
Это означает, что следующее не применяется:
[C++11: 12.2/1]:
Временные объекты типа class создаются в различных контекстах: привязка ссылки к prvalue (8.5.3), возврат prvalue (6.6.3), преобразование, создающее prvalue (4.1, 5.2. 9, 5.2.11, 5.4), генерирование исключения (15.1), вход в обработчик (15.3) и некоторые инициализации (8.5).
[C++11: 6.6.3/2]:
Оператор return без выражения и списка инициализации в фигурных скобках может использоваться только в функциях, которые не возвращают значение, т. е. функция с возвратом тип void, конструктор (12.1) или деструктор (12.4).
Оператор return с выражением непустого типа можно использовать только в функциях, возвращающих значение; значение выражения возвращается вызывающей стороне функции. Значение выражения неявно преобразуется в возвращаемый тип функции, в которой оно появляется. Оператор return может включать создание и копирование или перемещение временного объекта (12.2). [ Примечание. Операция копирования или перемещения, связанная с оператором return, может быть опущена или рассматриваться как rvalue для разрешения перегрузки при выборе конструктора (12.8). —конец примечания ] Оператор return с списком инициализации в фигурных скобках инициализирует объект или ссылку, которые должны быть возвращены из функции с помощью инициализации списка копирования (8.5.4). из указанного списка инициализаторов. [ Пример:
std::pair<std::string,int> f(const char* p, int x) {
return {p,x};
}
—конец примера ]
Кроме того, даже если мы интерпретируем следующее как означающее, что выполняется инициализация нового ссылочного объекта, референт вероятно все еще жив в это время:
[C++11: 8.5.3/2]:
Ссылка не может быть изменена для ссылки на другой объект после инициализации. Обратите внимание, что инициализация ссылки обрабатывается совершенно иначе, чем присваивание ей. Передача аргумента (5.2.2) и возврат значения функции (6.6.3) являются инициализациями.
- Это делает #1 действительным.
Однако ваша инициализация новой ссылки ref
внутри main
явно нарушает [C++11: 8.3.2/5]
. Я не могу найти формулировку для этого, но само собой разумеется, что область действия функции была закрыта при выполнении инициализации.
- Это сделает №2 (и, следовательно, №3) недействительным.
По крайней мере, кажется, что в стандарте больше ничего не говорится об этом вопросе, поэтому, если приведенных выше рассуждений недостаточно, мы должны заключить, что стандарт неоднозначен в этом вопросе. К счастью, на практике это не имеет большого значения, по крайней мере, в мейнстриме.
person
Lightness Races in Orbit
schedule
10.01.2012
ref
A&
- person king_nak   schedule 10.01.2012ref
– это ссылка, относящаяся к объекту из другого блока, который больше не существует. - person Lightness Races in Orbit   schedule 10.01.2012A const&
для № 2, иначе он не скомпилируется. Однако семантика того, о чем вы спрашиваете, не изменится. - person Lightness Races in Orbit   schedule 10.01.2012