С++: Срок службы временных аргументов?

При создании нового экземпляра MyClass в качестве аргумента для такой функции:

class MyClass
{
  MyClass(int a);
};    

myFunction(MyClass(42));

делает ли стандарт доступными грантополучателями к сроку деструктора?
В частности, могу ли я предположить, что он будет вызван перед следующим оператором после вызова myFunction()?

Ответ 1

Временные объекты уничтожаются в конце полного выражения, частью которого они являются.

Полное выражение - это выражение, которое не является суб-выражением какого-либо другого выражения. Обычно это означает, что он заканчивается на ; (или ) для if, while, switch и т.д.), Обозначая конец инструкции. В вашем примере это конец вызова функции.

Обратите внимание, что вы можете продлить время жизни временных файлов, привязывая их к ссылке const. Это продлевает срок службы до эталонного ресурса:

MyClass getMyClass();

{
  const MyClass& r = getMyClass(); // full expression ends here
  ...
} // object returned by getMyClass() is destroyed here

Если вы не планируете менять возвращенный объект, то это хороший трюк, чтобы сохранить вызов конструктора копии (по сравнению с MyClass obj = getMyClass();), в случае, если оптимизация значения возврата не применялась. К сожалению, это не очень хорошо известно. (Я полагаю, что семантика перемещения С++ 11 сделает ее менее полезной.)

Ответ 2

Все правильно сослались на 12.2/3 или подобное, что отвечает на ваш вопрос:

Временные объекты уничтожаются как последний шаг в оценке полное выражение, которое (лексически) содержит точку, в которой они были создан.

Мне показалось забавным, что на следующей странице в моей печати стандарта 12.2/4 говорит:

Существует два контекста, в которых временные другая точка, чем конец полное выражение.

Ни один из них не относится к вашему примеру, оба они относятся к использованию временных элементов в инициализаторах. Но это показывает, что вы должны держать свои мысли о себе, когда имеете дело с хитрым зверьком, подобным стандарту С++.

Ответ 3

Стандарт действительно предлагает гарантии - из раздела 12.2/5:

Временная привязка к ссылке параметр в вызове функции (5.2.2) сохраняется до завершения полное выражение, содержащее вызов

Однако в вашем коде неясно, будет ли параметр передаваться по ссылке или по значению, хотя в какой-то момент будет использоваться конструктор копирования, который принимает ссылку.

Ответ 4

В разделе 12.2 "Временные объекты", раздел 3, стандарт ANSI/ISO C гласит: "... Временные объекты уничтожаются как последний шаг при оценке полного выражения, которое (лексически) содержит точку, в которой они были созданы."

Это тесно связано с понятием Точки последовательности. Когда точка последовательности достигнута, все побочные эффекты выражений гарантированно имели место.