C++17 копирование elision и уничтожение объектов

Из сравнения,

Когда происходит удаление копии, реализация обрабатывает источник и цель пропущенной операции копирования / перемещения (начиная с C++11) просто как два разных способа обращения к одному и тому же объекту, и уничтожение этого объекта происходит позднее случаи, когда два объекта были бы уничтожены без оптимизации (за исключением того, что если параметр выбранного конструктора является rvalue ссылкой на тип объекта, уничтожение происходит, когда цель будет уничтожена) (начиная с C++17).

Для простого случая, как A a = returnA();Я могу понять, что объект не разрушен в returnA() и вместо этого происходит разрушение, как в случае A a; который позже.

Я не могу вспомнить случай, когда происходит обратное, так что источник операции копирования / перемещения уничтожается первым. Также я хотел бы получить пример добавленной инструкции начиная с C++17 (исключение, когда параметр выбранного конструктора является rvalue ссылкой на тип объекта)

1 ответ

Решение

Симметричный случай, когда источник переживает цель, это когда параметр prvalue является параметром:

struct A {
  static int *data;
  A() {if(!refs++) data=new int(42);}
  A(const A&) {++refs;}  // not movable
  ~A() {if(!--refs) delete data;}
private:
  static int refs;
};
int A::refs,*A::data;
int* f(A) {return A::data;}
A returnA();
int returnInt() {return *f(returnA());} // ok

Потому что результат returnA() является временным, его срок службы распространяется до конца return полное выражение заявления. Реализация может идентифицировать это с fпараметр, но не может уничтожить его, когда f возвращается, поэтому разыменование в returnInt является действительным. (Обратите внимание, что параметры могут сохраняться так долго.)

Корректировка в C++17 (наряду с гарантией такого исключения) заключается в том, что если вы (будете) перемещать значение prvalue, оно может быть уничтожено, когда параметр имеет значение (так как вы не должны полагаться на его содержимое в любом случае). Если это когда f возвращается, (опрометчивый) код выше становится недействительным, если A сделан подвижным

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