Симметричный случай, когда источник переживает цель, когда 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 (наряду с гарантированным таким исключением) такова, что если вы () move значение, оно может быть уничтожено, когда параметр имеет значение (так как вы не должны полагаться на его содержимое в любом случае).Если в этот момент возвращается f
, приведенный выше (опрометчивый) код становится недействительным, если A
сделан подвижным.