2012-05-10 30 views
5

Esta pregunta se puede considerar una continuación de la siguiente pregunta: C++ temporary variable lifetime.C++: variables temporales y su duración

Qt contenedores admiten la sintaxis de inicialización stream-like. Ahora, cuando escribo el siguiente código, mi QVector se destruye inmediatamente después de la asignación y la referencia se vuelve colgante.

const QVector<QString>& v = QVector<QString>() << "X" << "Y" << "Z"; 

correspondiente operator<< se implementa de la siguiente manera:

inline QVector<T> &operator<< (const T &t) 
{ append(t); return *this; } 

Por lo que yo sé, 10.4.10 Temporary Objects establece que el tiempo de vida de un objeto temporal se extiende para que coincida con el tiempo de vida del correspnding const referencia a eso

Sin embargo, en este caso el objeto temporal QVector<QString>()se destruye antes.

supongo que, probablemente, esto sucede debido al hecho de que la última operación devuelve un QVector<QString>& y no debe saber nada de la vida útil del temporal QVector<QString>, pero esta explicación no es estricta y podría estar equivocado.

Entonces, ¿por qué sucede esto?

+3

"* supongo que probablemente esto sucede debido a ... * "Estás más o menos en lo cierto, pero la explicación técnica sería que un valor r se está descomponiendo en un valor l. – ildjarn

+0

Creo que el 'temporal' está vinculado a la referencia * returned * de * operator << * pero al final de la' expresión' se destruye. El estándar solo garantiza el tiempo de vida 'temporal' vinculado al * const ref *, no las referencias temporales a ellos. –

+0

Me doy cuenta de que su pregunta satisface la curiosidad académica, pero en la práctica, puede hacer que 'v' no sea una referencia como esta:' const QVector v = QVector () << "X" << "Y" << " Z ";' –

Respuesta

7

El tiempo de vida de un temporal se extiende sólo si se vincula a una constante referencia:

const QVector<QString>& v = QVector<QString>(); 

Sin embargo, en su código que está no vinculante del temporal para nada. Más bien, está llamando a una función miembro (del temporal), que devuelve una referencia (a la temporal). El resultado de esta llamada de función ya no es un objeto temporal, sino simplemente una referencia simple. El objeto temporal original expira al final de la expresión completa en la que aparece, y la referencia v se convierte en colgando.

(En el nuevo C++, es posible prohibir este tipo de "accidentes" en virtud de las funciones miembro rvalue cualificado, es decir, usted podría =delete la versión rvalue del operador <<.)

Cuestiones relacionadas