Может ли вторая ссылка Const продлить срок службы временного

  • Фон:

Я заметил, что подпись std::max:

шаблон
const T& max(const T&, const T&);

и я задавался вопросом о последствиях возвращения ссылки на const T...

Если мы передадим два L-значения, то имеет смысл вернуть ссылку на одно из двух. Но если мы передадим две PR-значения, что возвращается и безопасно ли это использовать?

Проблема:

Я говорил с некоторыми коллегами, и вот минимальный рабочий пример проблемы: http://cpp.sh/4en4

#include <iostream>
int glob = 100;
class temp{
  int* val;
public:
  temp(int n = 0){
    val = new int(n);
  }
  void print() const{ std::cout << "I store " << *val << std::endl; }
  ~temp(){
    std::cout << "temp object died" << std::endl;
    delete val;
    val = &glob;
  }
};
const temp& foo(const temp& a){
  return a;    
}

int main(){
  const temp& b = foo(2); 
  std::cout << "Is it safe?" << std::endl;
  b.print(); 
}

Без оптимизации:

 временный объект умер
Это безопасно?
Я храню 100 

С умеренным:

 временный объект умер
Это безопасно?
Я храню -1992206527 

Запуск этого с разными уровнями оптимизации дает разные результаты. Однако во всех случаях возврат ссылки не продлевает время жизни локального объекта; его дескриптор по-прежнему вызывается, хотя в одном случае мы, кажется, восстанавливаем ссылку на уничтоженный объект, а в другом мы, кажется, имеем висячий указатель.

Стандарт:

Цитирование из стандарта C++, номер документа N4618:

12.2 пункт 6:

... когда ссылка связана с временным. Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъекта, к которому привязана ссылка, сохраняется в течение всего времени существования ссылки, за исключением:
(6.1) - Временный объект, связанный с опорным параметром в вызове функции (5.2.2), сохраняется до завершения полного выражения, содержащего вызов.
(6.2) - Срок действия временной привязки к возвращенному значению в операторе возврата функции (6.6.3) не продлевается; временное уничтожается в конце полного выражения в операторе возврата. "

Из (6.1) может показаться, что временный foo (2) должен существовать для всего оператора, который инициализирует b.

Из (6.2) может показаться, что локальное "а" уничтожается, что фактически уничтожает временный foo(2), в результате чего b принимает разрушенное значение.

Мои вопросы:

1a. Что такое полное выражение, которое содержит временную сгенерированную foo(2) в const temp& b = foo(2);

1б. Может ли вторая ссылка const продлить срок службы временного?

  1. Почему std::max реализован как таковой, учитывая очевидную опасность?

0 ответов

Другие вопросы по тегам