2012-03-11 20 views
17

En el último estándar de C++ que implica que:C++ 11: La declaración de rango para: duración de "inicio de rango"?

for (foo : bar) 
    baz; 

es equivilant a:

{ 
    auto && r = bar; 
    for (auto it = r.begin(), end = r.end(); it != end; ++it) 
    { 
     foo = *it; 
     baz; 
    } 
} 

Cuando la barra de lo anterior es una llamada a una función que devuelve una colección, por ejemplo:

vector<string> boo(); 

es decir

for (auto bo : boo()) 
    ... 

la línea no se convierten en:

auto&& r = boo(); 
... 

Y así, el valor de retorno temporal de Boo() es destruido al final de la declaración "auto & & r = Boo()", y luego r es una referencia colgante a la entrada del ciclo. ?? ¿Es este razonamiento correcto? ¿Si no, porque no?

+1

En primer lugar, 'vector boo();' NO declara un objeto. Declara una función. Segundo, no entiendo tu pregunta. – Nawaz

+6

Sí "vector boo()" es la firma de una función de ejemplo que devuelve una colección. La función se llama en la línea de abajo. –

Respuesta

15

¿Es este razonamiento correcto? ¿Si no, porque no?

Es correcto hasta este punto:

Y así, el valor de retorno temporal de Boo() es destruido al final de la declaración "auto & & r = Boo()" [. ..]

Enlazando un temporal a una referencia extiende su vida útil a la de la referencia. Por lo tanto, el temporal dura todo el ciclo (por eso también existe un conjunto adicional de {} en todo el constructo: para limitar correctamente la duración de ese temporal).

Esto es de acuerdo con el párrafo 5 de §12.2 de la norma C++:

El segundo contexto es cuando una referencia está unido a un temporal. El temporal a la que la referencia está unido, o el temporal que es el objeto completa de un subobjeto en que la referencia está obligado persiste durante toda la vida útil de la referencia, excepto:

[varias excepciones que no se aplican aquí ]

Ésta es una propiedad interesante que permite abusar de la oscilado-bucle for cosas no rangey: http://ideone.com/QAXNf

+0

¿Tiene una referencia estándar para eso? –

+0

@ user1131467 Proporcioné la cita adecuada (no perdí las excepciones a la regla: la cita sería demasiado larga). –

6

el razonamiento no es correcto porque boo devuelve un objeto temporal por valor. Al vincular este objeto temporal a una referencia, se amplía la vida útil del temporal. Cita estándar (§ 12.2/5):

[...] El temporal en el que la referencia es unido o el temporal que es el objeto completo de un subobjeto a la que la referencia está obligado persiste durante toda la vida de la referencia [...]

El razonamiento sería correcto si boo devolviera una referencia. Un ejemplo para una expresión que devuelve una referencia a un temporal es string("a") += string("b"); el uso de este valor en un bucle for basado en rango da lugar a un comportamiento indefinido.