c++ loops range auto

c++ - En ''for(auto c: str)'', ¿qué es exactamente c?



loops range (7)

En '' for (auto c : str) '', ¿qué es exactamente c?

c es una variable local con almacenamiento automático dentro del alcance de la declaración de rango. Su tipo se deducirá porque usó auto . En caso de string str="ARZ"; , el tipo deducido será char .

Presumiblemente, c es solo un puntero en el vector

No hay vector, y c no es un puntero. Es un char .

Comprender lo que hace el rango puede ayudar. Es equivalente a hacer lo siguiente (las variables prefijadas __ no son accesibles para el programador; son conceptuales para el comportamiento del bucle):

{ auto && __range = range_expression; auto __begin = begin_expr; auto __end = end_expr; for (; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }

O, en este caso particular:

{ auto && __range = str; auto __begin = range.begin(); auto __end = range.end(); for ( ; __begin != __end; ++__begin) { auto c = *__begin; // note here cout << (void*)&c << endl; } }

Tenga en cuenta que si usa auto& , entonces se deducirá que c es una referencia a char. La aplicación del operador addressof a una referencia no producirá la dirección de la variable de referencia, sino la dirección del objeto referido. En este caso, el objeto referido sería el carácter dentro de la cadena.

Si declaro:

string s = "ARZ";

Y luego ejecuta el siguiente código:

for (auto& c : s) { cout << (void*)&c << endl; }

los resultados corresponderán a las direcciones de s[0] , s[1] y s[2] respectivamente.

Si elimino el & y ejecuto:

for (auto c : s) { cout << (void*)&c << endl; }

La dirección de c es siempre la misma.

Presumiblemente, c es solo un puntero en el vector y su valor avanza por sizeof(char) con cada bucle, pero me resulta difícil entender por qué no estoy obligado a escribir *c para acceder a los valores de cadena de caracteres.

Y finalmente si corro:

for (auto c: s) { c=''?''; cout << c << endl; }

Imprime 3 signos de interrogación.

¿Me resulta difícil comprender qué es realmente c ?


En ''for (auto c: str)'', ¿qué es exactamente c?

Es una variable local cuyo alcance es el bloque completo y tiene el tipo char .

for (auto c : str) { loop_statement }

es equivalente a

{ for (auto __begin = str.begin(), __end = str.end(); __begin != __end; ++__begin) { auto c = *__begin; loop_statement } }

En algunas implementaciones, en algunas condiciones, dado que la vida útil de c finaliza antes de que comience la vida útil de c de la próxima iteración, se asigna en el mismo lugar y obtiene la misma dirección. No puedes confiar en eso.


Cuando usa referencias, la referencia c es una referencia a un carácter dentro de la cadena.

Cuando no usa referencias, c es una variable char simple, que contiene una copia del carácter en la cadena.

La razón por la que la variante sin referencia proporciona el mismo puntero para todas las iteraciones es simplemente un detalle de implementación, donde el compilador reutiliza el espacio para la variable c dentro de cada iteración.


En este rango para bucle

for (auto c: s) {c=''?''; cout << c << endl;}

hay tres iteraciones porque el tamaño de la cadena s es igual a 3 .

Dentro del bucle, el valor asignado del objeto c se ignora y el objeto es reasignado por el carácter ''?'' . Entonces tres personajes ''?'' son emitidos

El tipo de la variable local c es char que es el tipo de valor de la clase std::string

En este rango para bucle

for (auto& c : s) cout << (void*)&c << endl;

la variable c tiene un tipo referenciado más precisamente el tipo char & . Entonces, en este bucle, se emiten las direcciones de los objetos referenciados. Es decir, en este bucle se envían las direcciones de los elementos de la cadena.

En este rango para bucle

for (auto c : s) cout << (void*)&c << endl;

se emite la dirección de la misma variable local c .


Si no conoce el tipo, puede dejar que el compilador le diga:

#include <string> template <typename T> struct tell_type; int main(){ std::string s = "asdf"; for (auto& c : s) { tell_type<decltype(c)>(); } }

Tenga en cuenta que no hay una definición para tell_type , por lo tanto, esto dará como resultado un error en la línea de:

error: implicit instantiation of undefined template ''tell_type<char>''

Y de manera similar

error: implicit instantiation of undefined template ''tell_type<char &>''

para el for (auto& ... loop.


c es char .

La sintaxis puede ser engañosa hasta que la tenga debajo de la piel (pero tiene sentido).

for (auto c : s) //*distinct object* (think: a copy usually) for (auto& c : s) //reference into the string (can modify string)

Corto: use auto& cuando necesite modificar el contenido.


for (auto& c : s)

c es una reference a un personaje ( char& )

Este bucle es más o menos equivalente a C:

for (char* c=str; *c; ++c)

for (auto c : s)

c es un personaje ( char )

Este bucle es más o menos equivalente a C:

int i=0; for (char c=str[i]; i<strlen(str); c=str[++i])