Когда вы пишете функцию, таким образом, ...
const S& f(int i) const { std::cout << i << "\n"; return *this; }
... вы сообщаете компилятор, чтобы вернуть const S&
и вы принимаете на себя ответственность за обеспечение ссылочного объекта имеет срок службы, подходящий для вызывающего абонента использовать. («обеспечение» может представлять собой документирование использования клиента, которое правильно работает с вашим дизайном.)
Часто - с типичным разделением кода на заголовки и файлы реализации - реализация f(int) const
даже не будет видна вызывающему коду, а в в таких случаях компилятор не знает, в отношении которого S
может быть возвращена ссылка, а также то, что это S
является временным или нет, поэтому у него нет оснований для принятия решения о необходимости продления срока службы.
Помимо очевидных опций (например, доверенных клиентов для написания безопасного кода, возврата по значению или умного указателя), стоит знать о более неясном варианте ...
const S& f(int i) const & { ...; return *this; }
const S f(int i) const && { ...; return *this; }
&
и &&
непосредственно перед перегружать функциональные органы f
таким образом, что версия &&
используется, если *this
выполнен с возможностью перемещения, в противном случае используется версия &
. Таким образом, кто-то, связывающий const &
с номером f(...)
, вызывается на объект, который истекает, будет привязан к новой копии объекта и продлить срок службы на локальную ссылку const
, тогда как когда объект не истечет (пока) ссылка const
будет к исходному объекту (который до сих пор не гарантируется вживую до тех пор, пока ссылка - требуется некоторая осторожность).
'f' возвращает значение lvalue, а не prvalue. –
И время жизни 'S()' заканчивается в конце полного утверждения. – Jarod42
@KerrekSB почему lvalue? Мы не можем поместить 'f' в левой части' = '. – alexolut