Подтвердить что ты не робот

С++ возвращаемое значение, созданное до или после уничтожения auto var?

В С++ гарантируется, что возвращаемое значение будет создано до того, как будут уничтожены автоматические переменные в функции? Уведомление Корзина:: получить:

class Basket
{
public:
  // Gift is a struct containing safely copyable things like int or string
  Gift gift;
  // Used to protect access and changes to gift
  Mutex mutex;

  // Copy gift into present, while locked to be thread safe
  void put (const Gift & gift)
  {
    Lock lock(mutex);   // Constructor locks, destructor unlocks mutex
    this->gift = gift;  // Gift assignment operator
  }

  // Return a memberwise-copy of gift, tries to be thread safe (but is it?)
  Gift get ()
  {
    Lock lock(mutex);  // Constructor locks, destructor unlocks mutex
    return gift;       // Gift copy constructor
  }
};

Мне нужна корзина:: получите, чтобы выполнить свой конструктор копии копии (возвращаемого объекта temp) до уничтожения объекта блокировки. В противном случае возвращаемый объект-подарок может быть поврежден одновременным вызовом.

Мои тесты показывают, что подарочная копия действительно создана до уничтожения блокировки, однако она гарантирована? Если нет, мне нужно создать вторую временную функцию внутри функции, например:

  Gift get ()
  {
    Gift result;
    {
      Lock lock(mutex);
      result = gift;
    }
    return result;
  }
4b9b3361

Ответ 1

Да, автоматическая переменная останется в области действия до тех пор, пока результат не будет завершен. Это особенно актуально, если вы используете компилятор, который оптимизирует return, например:

Gift get() 
{ 
    Lock lock(mutex);
    return gift;
} 

Gift g = basket.get();

Что было бы эквивалентно этой последовательности:

Gift g;
Lock lock(mutex);
g = Gift(gift);
~lock();

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

void get(Gift &ret) 
{ 
    Lock lock(mutex);
    ret = gift;
} 

Gift g;
basket.get(g);

Что было бы эквивалентно этой последовательности:

Gift g;
Lock lock(mutex);
g = gift;
~lock();

Другими словами, временное может быть удалено во время return.

Ответ 2

Это гарантировано. Возвращаемое значение копируется (если необходимо) до разрушения. Здесь аналогичный вопрос/ответ, который дает хорошее описание последовательности.

Сфера и возвращаемые значения в С++