¿Cuáles son las ventajas y desventajas de utilizar la auto
palabra clave, especialmente en bucles for?
for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->something();
}
for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->second->something();
}
for(auto it = x.begin(); it != x.end(); it++ )
{
it->??
}
Parece como si no sabe si tiene un iterador para un mapa o un vector no vas a saber si se debe utilizar first
o second
o sólo directamente propiedades de acceso del objeto, ¿no?
Esto me recuerda el debate de C # sobre si usar la palabra clave var
. La impresión que tengo hasta ahora es que en el mundo de C ++ la gente está lista para adoptar la auto
palabra clave con menos pelea que var
en el mundo de C #. Para mí, mi primer instinto es que me gusta saber el tipo de variable para poder saber qué operaciones puedo realizar en ella.
var
? Me lo perdí.for (auto& it : x)
(o sin referencia si desea copiar)x
y ni siquiera sabes quéx
es, no deberías escribir ese bucle en primer lugar ;-)Respuestas:
Las motivaciones en C ++ son más extremas, ya que los tipos pueden volverse mucho más intrincados y complejos que los tipos C # debido a la metaprogramación y otras cosas.
auto
es más rápido de escribir y leer y más flexible / mantenible que un tipo explícito. Quiero decir, ¿quieres empezar a escribir?Eso ni siquiera es el tipo completo. Me perdí un par de argumentos de plantilla.
fuente
auto
está. Por diseño.typedef
ayuda, peroauto
ayuda más.En tu ejemplo:
Tiene que haber una declaración para
x
visible. Por lo tanto, el tipo deit
debe ser obvio. Si el tipo dex
no es obvio, entonces el método es demasiado largo o la clase es demasiado grande.fuente
x
es un nombre de variable muy malo para un contenedor. En algunas situaciones, lo más probable es que solo mire el nombre (semánticamente valioso) e infiera las posibles operaciones.x
como un ejemplo genérico, tiendo a usar nombres de variables bastante descriptivos.¡ Objeción ! Pregunta cargada.
¿Me puede explicar por qué el tercer código tiene
??
, pero el primero y el segundo no? Para ser justos, su código debe leer lo siguiente:Allí. Mismo problema aunque no lo hayas usado
auto
.Y en todos los casos, la respuesta es la misma: el contexto importa . No se puede hablar de manera significativa sobre un fragmento de código de forma aislada. Incluso si no hubiera utilizado plantillas pero algún tipo concreto, esto solo habría trasladado el problema a otro lugar, ya que el lector de su código tendría que saber sobre la declaración de dicho tipo.
Si el uso
auto
en esas situaciones hace que su código sea ilegible, debe tratar esto como una señal de advertencia de que hay algo mal con el diseño de su código. Por supuesto, hay casos en los que los detalles de bajo nivel son importantes (como cuando se trata de operaciones de bits o API heredadas) en los que un tipo explícito podría ayudar a la legibilidad. Pero en general, no.En cuanto a
var
(ya que lo mencionaste explícitamente), también hay un gran consenso en la comunidad de C # para usarvar
. Los argumentos en contra de su uso generalmente se basan en falacias .fuente
T
es tan opaca al usuario comoauto
. Sin embargo, se supone que uno está bien y el otro no. Eso no tiene sentido. En el caso de OP,T
es un sustituto de un tipo arbitrario. En código real, puede ser el uso de plantillas(for typename std::vector<T>::iterator…)
o una interfaz de clase. En ambos casos, el tipo real está oculto para el usuario y, sin embargo, habitualmente escribimos dicho código sin problemas.auto
. Es trivial ver qué operacionesx
admite el contexto. De hecho, el tipo no le proporciona información adicional: en cualquier caso necesita algo secundario (IDE, documentación, conocimiento / memoria) para indicarle el conjunto de operaciones compatibles.begin
retorna pero sí sabe quéstd::vector<>::iterator
es. Y debe utilizar una herramienta de programación incorrecta que no pueda proporcionarle esta información de manera trivial. Esto es muy complicado. En realidad, ya sea que sabe tantobegin
yiterator
o ninguno, y que usted debe utilizar un IDE o editor que fácilmente puede hacer que la información relevante disponible para usted. Todo IDE moderno y editor de programación puede hacer eso.PRO
Tu codigo :
no se va a compilar, debido al nombre dependiente de la plantilla.
Esta es la sintaxis correcta:
Ahora mire cuánto dura la declaración de tipo. Esto explica por qué
auto
se introdujo la palabra clave. Esta :Es más conciso. Entonces, esto es un profesional.
ESTAFA
Tienes que tener un poco de cuidado. Con la palabra clave
auto
, obtienes el tipo que declaraste.Por ejemplo :
vs
Para concluir: sí, debería hacerlo, pero no usarlo en exceso. Algunas personas tienden a usarlo demasiado y a poner el auto en todas partes, como en el siguiente ejemplo:
vs
fuente
auto i = 0
. Culpable. Yo hago eso. Pero eso es porque sé que0
es un literal de tipoint
. (y una constante octal ;-))¡Si deberías!
auto
no borra el tipo; incluso si "no sabe" quéx.begin()
es, el compilador lo sabe e informará de un error si intenta utilizar el tipo incorrectamente. Además, no es inusual emularmap
con avector<pair<Key,Value>>
, por lo que el uso del códigoauto
funcionará para ambas representaciones de diccionario.fuente
Sí, debe usar
auto
como regla predeterminada. Tiene ventajas crudas sobre especificar explícitamente el tipo:Aquí es donde puedes elegir. También hay casos en los que no tienes otra opción:
Siempre que sepa exactamente lo que
auto
hace, no tiene inconvenientes.fuente