I ++ progetti Uniti C:Copia elision e temporanei legati-by-ref oggetto
12.8p31 Questa elisione delle operazioni di copia/spostamento, chiamato copia elisione, è consentito nei seguenti casi (che possono essere combinati per eliminare le copie multiple):
(...)
- quando un oggetto di classe temporanea che non è stato legato a un riferimento (12.2) sarebbe copiato/spostato per un oggetto di classe con lo stesso tipo cv-qualificato, l'operazione di copia/spostamento può essere omesso dal costruire l'oggetto temporaneo direttamente nella destinazione della copia omessa/spostare
In altre parole:
X MakeX() {
return X(); // Copy elided
}
X MakeX() {
const X& x = X(); // Copy not elided
return x;
}
Qual è la ragione di tale restrizione per i riferimenti?
Si prega di non concentrarsi sulla validità dei seguenti esempi, in quanto sono solo per esemplificare che non riesco a vedere la differenza (IMHO) tra temporanea e un riferimento.
Da una parte dall'introduzione del riferimento abbiamo permesso ad altri peer di creare un alias dello stesso oggetto, mentre il chiamante di MakeX()
si aspetta che sia sicuro e pulito.
class Y {
public:
Y(const X& x) : _xRef(x) {}
private:
const X& _xRef;
};
X MakeX() {
const X& x = X();
Y y{x};
StaticStuff::send(y);
return x; // Oops, I promised to return a clean,
// new object, but in fact it might be silently
// changed by someone else.
}
Ma per quanto riguarda questo caso (probabilmente si tratta di UB;)):
class Y {
public:
Y(X* x) : _xPtr(x) {}
private:
X* _xRef;
};
X MakeX() {
X x;
Y y{&x}; // I'm referencing a local object but I know it will be
// copy elided so present in the outer stack frame.
StaticStuff::send(y);
return x; // Copy elided?
}
'StaticStuff :: send (y);' in realtà non introduce la possibilità di modificare 'x' indirettamente => il suo comportamento indefinito usa un riferimento a' x' dopo la fine di 'MakeX'. –
'Oops, ho promesso di restituire un oggetto nuovo e pulito, ma in effetti potrebbe essere cambiato silenziosamente da qualcun altro. - Cosa intendi? 'x' è' const X & 'quindi non modificabile. –
la tua seconda versione di 'MakeX' probabilmente invocherebbe il costruttore di copie per trasformare' const X &' in una semplice 'X', è questo il problema che hai? – didierc