¿Hay una desventaja en declarar variables con auto en C ++?

143

Parece que autofue una característica bastante importante para agregar en C ++ 11 que parece seguir muchos de los lenguajes más nuevos. Al igual que con un lenguaje como Python, no he visto ninguna declaración explícita de variables (no estoy seguro de si es posible usar los estándares de Python).

¿Hay algún inconveniente en usar autopara declarar variables en lugar de declararlas explícitamente?

DxAlpha
fuente
1
Consulte también: stackoverflow.com/questions/6434971/… , stackoverflow.com/questions/15254461/… , stackoverflow.com/questions/6900459/… , stackoverflow.com/questions/8430053/is-c11-auto-type-dangerous , y tal vez otros. No estoy seguro si estos son duplicados exactos, pero definitivamente son candidatos.
Cody Gray
3
El único inconveniente que encontré fue cuando tuve que portar una base de código a una plataforma (consola) cuyo compilador no admitía (y no tenía intención de admitir) las características de C ++ 11.
Sam
77
Solo para completar GotW # 94 "Casi siempre automático": herbsutter.com/2013/08/12/…
Richard Critten
1
Estaba escuchando cppcast y se mencionó la inicialización de clash b / w auto y list. Trataré de encontrar ese podcast.
Abhinav Gauniyal
2
El primer inconveniente, creo, está afectando la legibilidad del código
ggrr

Respuestas:

111

Solo ha preguntado acerca de los inconvenientes, por lo que estoy destacando algunos de ellos. Cuando se usa bien, autotiene varias ventajas también. Los inconvenientes resultan de la facilidad de abuso y del mayor potencial para que el código se comporte de manera no intencional.

El principal inconveniente es que, al usar auto, no necesariamente conoce el tipo de objeto que se está creando. También hay ocasiones en las que el programador puede esperar que el compilador deduzca un tipo, pero el compilador deduce firmemente otro.

Dada una declaración como

auto result = CallSomeFunction(x,y,z);

no necesariamente tienes conocimiento de qué tipo resultes. Puede ser un int. Puede ser un puntero. Puede ser otra cosa. Todos ellos admiten diferentes operaciones. También puede cambiar drásticamente el código mediante un cambio menor como

auto result = CallSomeFunction(a,y,z);

porque, dependiendo de las sobrecargas que existan para CallSomeFunction()el tipo de resultado, puede ser completamente diferente y, por lo tanto, el código posterior puede comportarse de manera completamente diferente de lo previsto. Es posible que de repente active mensajes de error en el código posterior (p. Ej., Posteriormente intente desreferenciar un mensaje int, intente cambiar algo que es ahora const). El cambio más siniestro es donde su cambio pasa por el compilador, pero el código posterior se comporta de formas diferentes y desconocidas, posiblemente con errores.

Por lo tanto, no tener un conocimiento explícito del tipo de algunas variables hace que sea más difícil justificar rigurosamente una afirmación de que el código funciona según lo previsto. Esto significa un mayor esfuerzo para justificar las afirmaciones de "apto para el propósito" en dominios de alta criticidad (por ejemplo, críticos de seguridad o críticos de misión).

El otro inconveniente más común es la tentación de un programador de utilizarlo autocomo un instrumento contundente para forzar la compilación del código, en lugar de pensar en lo que está haciendo el código y trabajar para hacerlo bien.

Peter
fuente
58
Es interesante notar que si tales ejemplos son el inconveniente de usar auto, ¡entonces la mayoría de los lenguajes de pato sufren tal inconveniente por diseño!
Leben Asa
11
Si CallSomeFunction()devuelve un tipo diferente dependiendo de la secuencia de sus argumentos, ese es un defecto de diseño CallSomeFunction(), no un problema de auto. Si no lee la documentación de una función que está utilizando antes de usarla, es un defecto del programador, no un problema auto. - Pero entiendo que estás jugando al abogado del diablo aquí, es solo que Nir Friedman tiene el caso mucho mejor.
DevSolar
16
@DevSolar: ¿Por qué sería T CallSomeFunction(T, int, int)un defecto de diseño? Obviamente, "devuelve un tipo diferente dependiendo de la secuencia de sus argumentos".
MSalters
9
"El principal inconveniente es que, al usar auto, no necesariamente conoce el tipo de objeto que se está creando". ¿Puede explicar por qué esto es un problema autoy no un problema con los temporales de subexpresión? ¿Por qué es auto result = foo();malo, pero foo().bar()no?
Angew ya no está orgulloso de SO
24
Según los comentarios, el "inconveniente" se está interpretando como una razón por la que algo es inaceptable. Una desventaja de una función de lenguaje es una desventaja que el desarrollador debe considerar y justificar aceptar o no, es decir, hacer compensaciones de ingeniería. No estoy haciendo afirmaciones generales sobre por qué la función debe o no debe usarse.
Peter
76

Esto no es autoexactamente un inconveniente de una manera basada en principios, pero en términos prácticos parece ser un problema para algunos. Básicamente, algunas personas: a) tratan autocomo un salvador para los tipos y apagan su cerebro cuando lo usan, o b) olvidan que autosiempre se deduce el valor de los tipos. Esto hace que las personas hagan cosas como esta:

auto x = my_obj.method_that_returns_reference();

Vaya, solo copiamos en profundidad algún objeto. A menudo es un error o un fallo de rendimiento. Luego, también puedes girar hacia el otro lado:

const auto& stuff = *func_that_returns_unique_ptr();

Ahora obtienes una referencia colgante. Estos problemas no son causados autoen absoluto, por lo que no los considero argumentos legítimos en su contra. Pero parece que autohace que este problema sea más común (desde mi experiencia personal), por las razones que enumeré al principio.

Creo que, con el tiempo, la gente se ajustará y comprenderá la división del trabajo: autodeduce el tipo subyacente, pero aún así desea pensar en la referencia y la constancia. Pero está tomando un poco de tiempo.

Nir Friedman
fuente
¿Por qué puedes copiar en profundidad un objeto costoso para empezar?
Laurent LA RIZZA
3
@LaurentLARIZZA: Algunas clases tienen constructores de copia simplemente porque a veces se necesitan (por ejemplo, instancias de std::vector). Ser costoso de copiar no es una propiedad de una clase, sino de objetos individuales. Por method_that_returns_referencelo tanto, podría referirse a un objeto de una clase que tiene un constructor de copia, pero cuyo objeto resulta bastante costoso de copiar (y no se puede mover).
Marc van Leeuwen
@MarcvanLeeuwen: Si el objeto es costoso de copiar y no se puede mover, ¿por qué se almacenaría en un std::vector? (Porque podría, sí, o porque no controlas la clase, pero ese no es el punto) Si es costoso copiarlo (y no posee ningún recurso, porque es copiable), ¿por qué no usar COW en el objeto? La localidad de datos ya es eliminada por el tamaño del objeto.
Laurent LA RIZZA
2
@LaurentLARIZZA No es una instancia de que algo almacenado en un vector sea costoso, solo un ejemplo, por ejemplo, el vector <double> es costoso de copiar, es un trabajo de asignación de montón + O (N). Mudarse es un arenque rojo. La primera línea que mostré copiará, no se moverá, a menos que la referencia devuelta sea una referencia de valor. VACA realmente no es ni aquí ni allá. El hecho es que los objetos caros para copiar siempre existirán.
Nir Friedman
44
@Yakk No puede hacer eso con seguridad, porque podría cortar. Lo único seguro que puede hacer es = deleteesa sobrecarga. Aunque en general lo que dices es una solución. Este es un tema que he explorado, si está interesado: nirfriedman.com/2016/01/18/… .
Nir Friedman
51

Otras respuestas mencionan inconvenientes como "realmente no sabes cuál es el tipo de variable". Yo diría que esto está relacionado en gran medida con la convención de nomenclatura descuidada en el código. Si sus interfaces están claramente nombradas, no debería tener que preocuparse por el tipo exacto. Claro, auto result = callSomeFunction(a, b);no te dice mucho. Pero auto valid = isValid(xmlFile, schema);le dice lo suficiente para usar validsin tener que preocuparse de cuál es su tipo exacto. Después de todo, con solo if (callSomeFunction(a, b)), tampoco sabrías el tipo. Lo mismo con cualquier otro objeto temporal de subexpresión. Así que no considero que esto sea un verdadero inconveniente auto.

Diría que su principal inconveniente es que a veces, el tipo de retorno exacto no es con el que desea trabajar. En efecto, a veces el tipo de retorno real difiere del tipo de retorno "lógico" como un detalle de implementación / optimización. Las plantillas de expresión son un excelente ejemplo. Digamos que tenemos esto:

SomeType operator* (const Matrix &lhs, const Vector &rhs);

Lógicamente, esperaríamos SomeTypeserlo Vector, y definitivamente queremos tratarlo como tal en nuestro código. Sin embargo, es posible que para fines de optimización, la biblioteca de álgebra que estamos utilizando implemente plantillas de expresión, y el tipo de retorno real es este:

MultExpression<Matrix, Vector> operator* (const Matrix &lhs, const Vector &rhs);

Ahora, el problema es que MultExpression<Matrix, Vector>voluntad en toda tienda de probabilidad de que un const Matrix&e const Vector&internos; espera que se convierta a a Vectorantes del final de su expresión completa. Si tenemos este código, todo está bien:

extern Matrix a, b, c;
extern Vector v;

void compute()
{
  Vector res = a * (b * (c * v));
  // do something with res
}

Sin embargo, si hubiéramos usado autoaquí, podríamos tener problemas:

void compute()
{
  auto res = a * (b * (c * v));
  // Oops! Now `res` is referring to temporaries (such as (c * v)) which no longer exist
}
Angew ya no está orgulloso de SO
fuente
3
@NirFriedman Tienes razón, es fuerte, pero realmente siento que autotiene muy pocos inconvenientes, así que mantengo esa fortaleza. Y otros ejemplos de proxies, etc. incluyen varios "constructores de cadenas" y objetos similares encontrados en DSL.
Angew ya no está orgulloso de SO
2
Me han mordido las plantillas de expresión y autoantes, específicamente con la biblioteca Eigen. Es especialmente complicado porque el problema a menudo no aparece en las compilaciones de depuración.
Dan
1
El uso de autotambién puede morder cuando se usa la biblioteca de matriz Armadillo , que hace un uso intensivo de la metaprogramación de plantillas para fines de optimización. Afortunadamente, los desarrolladores han agregado la función .eval () que se puede utilizar para evitar los problemas conauto
mtall
2
"Si sus interfaces están claramente nombradas, no debería tener que preocuparse de cuál es el tipo exacto" Su compilador no puede verificar la exactitud de su código al estudiar los nombres de las variables. Este es el punto completo de un sistema de tipos. ¡Pasarlo ciegamente es una tontería!
Carreras de ligereza en órbita el
1
@Angew: No es un problema para los temporales porque generalmente los usas de inmediato, lo que autogeneralmente implica algún tipo de verificación de tipo (y las salpicaduras autoen todas partes eliminan la seguridad de ese tipo al igual que en cualquier otro lugar). No es una buena comparación.
ligereza corre en órbita el
13

Uno de los inconvenientes es que a veces no se puede declarar const_iteratorcon auto. Obtendrá un iterador ordinario (no constante) en este ejemplo de código tomado de esta pregunta :

map<string,int> usa;
//...init usa
auto city_it = usa.find("New York");
ks1322
fuente
3
Bueno, obtienes un iteratoren cualquier caso ya que tu mapa no es const. si desea convertirlo a a const_iterator, especifique el tipo de variable explícitamente como de costumbre o extraiga un método para que su mapa sea constante en el contexto de su find. (Prefiero el último. SRP.)
Laurent LA RIZZA
auto city_it = static_cast<const auto&>(map).find("New York")? o, con C ++ 17, auto city_if = std::as_const(map).find("New York").
Dev Null
11

Hace que su código sea un poco más difícil o tedioso de leer. Imagina algo así:

auto output = doSomethingWithData(variables);

Ahora, para determinar el tipo de salida, tendría que rastrear la firma de la doSomethingWithDatafunción.

Skam
fuente
40
No siempre. auto it = vec.begin();es mucho más fácil de leer que, std::vector<std::wstring>::iterator it = vec.begin();por ejemplo.
Jonathan Potter
44
Convenido. Depende del caso de uso. Podría haber sido más preciso al respecto.
Skam
1
@SeeDart, sí, las personas que usan automóviles de esa manera lo están haciendo mal.
lciamp
66
"Rastrear la firma de la función", si no se trata de pasar el mouse o presionar una tecla ("símbolo de seguimiento" / "ir a la declaración" / como se llame), debe configurar su editor más o cambie a un IDE que pueda hacer esto sin configuración ... Sin embargo, su punto sigue siendo válido.
hyde
66
¡Noté que no en un IDE sino en pequeñas mirillas de diferencias al revisar los registros! Con auto son más difíciles de leer por esa razón.
JDługosz
10

Como este desarrollador, odio auto. O más bien, odio cómo la gente usa mal auto.

Soy de la opinión (fuerte) que autoes para ayudarlo a escribir código genérico, no para reducir la escritura .
C ++ es un lenguaje cuyo objetivo es permitirle escribir código robusto, no minimizar el tiempo de desarrollo.
Esto es bastante obvio a partir de muchas características de C ++, pero desafortunadamente algunas de las más nuevas como autoesa reducen el tipeo y engañan a las personas para que piensen que deberían comenzar a ser flojos con el tipeo.

En los autodías anteriores , las personas usaban typedefs, lo cual fue genial porque typedef permitió que el diseñador de la biblioteca lo ayudara a determinar cuál debería ser el tipo de retorno, para que su biblioteca funcione como se esperaba. Cuando lo usas auto, le quitas ese control al diseñador de la clase y en su lugar le pides al compilador que descubra cuál debería ser el tipo, lo que elimina una de las herramientas C ++ más poderosas de la caja de herramientas y corre el riesgo de romper su código.

En general, si lo usa auto, debería ser porque su código funciona para cualquier tipo razonable , no porque sea demasiado vago para escribir el tipo con el que debería funcionar. Si lo usa autocomo una herramienta para ayudar a la pereza, entonces lo que sucede es que eventualmente comienza a introducir errores sutiles en su programa, generalmente causados ​​por conversiones implícitas que no ocurrieron porque lo usó auto.

Por desgracia, estos errores son difíciles de ilustrar en un breve ejemplo aquí porque su brevedad hace que sean menos convincentes que los ejemplos reales que se presentan en un proyecto de usuario - sin embargo, se producen fácilmente en el código de la plantilla-pesado que esperan ciertas conversiones implícitas a tomar sitio.

Si quieres un ejemplo, hay uno aquí . Sin embargo, una pequeña nota: antes de sentir la tentación de saltar y criticar el código: tenga en cuenta que muchas bibliotecas conocidas y maduras se han desarrollado en torno a conversiones tan implícitas, y están allí porque resuelven problemas que pueden ser difíciles, si no imposibles. para resolver lo contrario. Intenta encontrar una mejor solución antes de criticarlos.

usuario541686
fuente
3
which was great because typedef allowed the designer of the library to help you figure out what the return type should be, so that their library works as expected. When you use auto, you take away that control from the class's designer and instead ask the compiler to figure out what the type should beRealmente no es una buena razón IMO. Los IDE actualizados, Visual Studio 2015, por ejemplo, le permiten verificar el tipo de la variable al pasar el mouse por encima auto. Esto es * exactamente * igual que el typedefuno.
Sombrero Chicken
@JameyD: Le faltan varios puntos cruciales allí: (1) Su argumento IDE solo funciona si el tipo es concreto, no con plantilla. Los IDEs no pueden decirle el tipo correcto en el caso de los tipos dependientes, por ejemplo typename std::iterator_traits<It>::value_type. (2) El punto completo fue que el tipo inferido no necesita ser "exactamente el mismo" que el tipo correcto previsto por el diseñador anterior del código; al usar auto, está quitando la capacidad del diseñador para especificar el tipo correcto.
user541686
Básicamente estás hablando de representantes, que una de las respuestas ya menciona. Las plantillas de expresión y las tonterías <bool> de vectores no son códigos cotidianos para la mayoría de las personas. En la mayoría de las situaciones, no desea conversiones implícitas, y la ayuda automática con eso. Herb Sutter habla ampliamente sobre las ventajas del auto en una de sus publicaciones de blog, y no se trata principalmente de las pulsaciones de teclas, y tampoco se trata solo de código genérico. Además, el primer enlace que proporcionó, la publicación del blog es simplemente un consejo terrible (por lo que es criticado vociferantemente en su sección de comentarios).
Nir Friedman
@NirFriedman: "... vector<bool>tonterías" ... ¿perdón? ¿Cómo crees que bitsetse implementa? ¿O considera que los contenedores de bits no tienen sentido?
user541686
1
@NirFriedman: Nada sobre el vector <bool> es nuevo para mí. Lo que estoy tratando de decirte y que te estás negando descaradamente a entender es que, a los efectos de esta pregunta, el conjunto de bits no es diferente del vector <bool>: ambos usan proxies, porque los proxies se consideraron útiles , y el hecho de que los proxies son útiles es una realidad que debe aceptar en lugar de vivir en la negación. ¿Puedes dejar de convertir esto en un debate sobre si crees que los proxies son útiles? Ese no es el tema de debate, y además, su opinión sobre ellos es solo su opinión, no algún tipo de hecho.
user541686
6

autono tiene inconvenientes per se , y abogo por usarlo (a mano) en todas partes en el nuevo código. Permite que su código compruebe constantemente el tipo y evite sistemáticamente el corte silencioso. (Si se Bderiva de Ay una función que regresa de Arepente regresa B, entonces se autocomporta como se espera para almacenar su valor de retorno)

Sin embargo, el código anterior a C ++ 11 puede depender de conversiones implícitas inducidas por el uso de variables explícitamente tipadas. Cambiar una variable tipada explícitamente autopodría cambiar el comportamiento del código , por lo que será mejor que tenga cuidado.

Laurent LA RIZZA
fuente
El voto negativo es justo, pero ¿podría comentar por qué?
Laurent LA RIZZA
No te rechacé, pero autotiene inconvenientes per se (o al menos, muchos piensan que sí). Considere el ejemplo dado en la segunda pregunta en este panel de discusión con Sutter, Alexandrescu y Meyers: Si tiene auto x = foo(); if (x) { bar(); } else { baz(); }y foo()devuelve bool, ¿qué sucede si los foo()cambios devuelven una enumeración (tres opciones en lugar de dos)? El autocódigo continuará funcionando, pero producirá resultados inesperados.
einpoklum
@einpoklum: ¿Y el uso en boollugar de autocambiar algo en caso de una enumeración sin ámbito? Puedo estar equivocado (no puedo verificar aquí), pero creo que la única diferencia es que la conversión se boolproduce en la declaración de variable en lugar de en la evaluación de la condición en el if. Si se establece el enumalcance, la conversión a boolno se realizará sin un aviso explícito.
Laurent LA RIZZA
4

La palabra clave autosimplemente deduce el tipo del valor de retorno. Por lo tanto, no es equivalente a un objeto Python, p. Ej.

# Python
a
a = 10       # OK
a = "10"     # OK
a = ClassA() # OK

// C++
auto a;      // Unable to deduce variable a
auto a = 10; // OK
a = "10";    // Value of const char* can't be assigned to int
a = ClassA{} // Value of ClassA can't be assigned to int
a = 10.0;    // OK, implicit casting warning

Como autose deduce durante la compilación, no tendrá ningún inconveniente en tiempo de ejecución.

Leben Asa
fuente
1
Sí, básicamente hace lo que type()hace Python. Deduce el tipo, no crea una nueva variable de ese tipo.
lciamp
2
@lciamp En realidad, eso sería decltype. autoes para asignación de variables específicamente.
Cubic
4

Lo que nadie mencionó aquí hasta ahora, pero por sí mismo vale una respuesta si me lo preguntas.

Dado que (incluso si todos deberían saberlo C != C++) el código escrito en C puede diseñarse fácilmente para proporcionar una base para el código C ++ y, por lo tanto, puede diseñarse sin demasiado esfuerzo para ser compatible con C ++, esto podría ser un requisito para el diseño.

Conozco algunas reglas de las que algunas construcciones bien definidas Cno son válidas C++y viceversa. Pero esto simplemente daría lugar a archivos ejecutables rotos y se aplica la conocida cláusula UB, que la mayoría de las veces se nota por bucles extraños que provocan bloqueos o lo que sea (o incluso pueden pasar desapercibidos, pero eso no importa aquí).

Pero autoes la primera vez 1 esto cambia!

Imagine que lo utilizó antes autocomo especificador de clase de almacenamiento y transfiere el código. Ni siquiera necesariamente (dependiendo de la forma en que se usó) se "rompería"; en realidad podría cambiar silenciosamente el comportamiento del programa.

Eso es algo que uno debe tener en cuenta.


1 Al menos la primera vez que tengo conocimiento.

dhein
fuente
1
Obtendría un error de compilación de todos modos al intentar compilar.
Sombrero Chicken
@JameyD: ¿Qué haría eso? ¿Por qué 2 situaciones de código válidas con diferentes significados deben resultar siempre erróneas?
Dhein
8
Si confía en "ningún tipo implica int" en C, se merece todas las cosas malas que obtendrá de esto. Y si no confía en él, usarlo autocomo un especificador de clase de almacenamiento junto con un tipo le dará un buen error de compilación en C ++ (que es una buena cosa en este caso).
Angew ya no está orgulloso de SO
1
@Angew, bueno, ese es el caso al que me refiero, sí. No estoy haciendo esto Pero es algo que al menos debe tenerse en cuenta.
Dhein
3

Una razón por la que puedo pensar es que pierdes la oportunidad de obligar a la clase que se devuelve. Si su función o método devolvió un largo 64 bits, y solo quería un 32 sin signo int, entonces pierde la oportunidad de controlar eso.

kblansit
fuente
1
Hay static_cast, y el IIRC, por ejemplo, Meyers 'Effective Modern C ++ incluso recomienda usarlo para especificar el tipo de variable autoescrita.
hyde
2

Como describí en esta respuesta auto , a veces puede dar lugar a situaciones funky que no tenía la intención. Tienes que decir explícitamente auto&que tienes un tipo de referencia mientras lo haces solo autopuedes crear un tipo de puntero. Esto puede generar confusión al omitir todo el especificador, lo que da como resultado una copia de la referencia en lugar de una referencia real.

Pollo Sombrero
fuente
2
Eso no es funky. Eso es lo que autohace, nunca inferir una referencia ni un consttipo. Como autoreferencia, será mejor que lo uses auto&&. (una referencia universal) Si el tipo no es barato de copiar o posee un recurso, entonces el tipo no debe ser copiable para empezar.
Laurent LA RIZZA
1

Otro ejemplo irritante:

for (auto i = 0; i < s.size(); ++i)

genera una advertencia ( comparison between signed and unsigned integer expressions [-Wsign-compare]), porque ies un int firmado. Para evitar esto, debe escribir, por ejemplo

for (auto i = 0U; i < s.size(); ++i)

o tal vez mejor:

for (auto i = 0ULL; i < s.size(); ++i)
Paul R
fuente
1
Sí, este también me resulta irritante. Pero el agujero en el idioma está en otro lugar. Para que este código sea verdaderamente portátil, suponiendo sizedevoluciones size_t, tendrías que poder tener un me size_tgusta literal 0z. Pero puede declarar un UDL para hacer esto. ( size_t operator""_z(...))
Laurent LA RIZZA
1
Objeciones puramente teóricas: unsignedes muy probable que no sea lo suficientemente grande como para contener todos los valores de std::size_tlas arquitecturas convencionales, por lo que en el improbable caso de que alguien tuviera un contenedor con un número absurdamente gigantesco de elementos, el uso unsignedpodría causar un bucle infinito en el rango inferior de índices. Si bien es poco probable que esto sea un problema, std::size_tdebe usarse para obtener un código limpio que indique la intención correctamente. No estoy seguro de que incluso unsigned long longsea ​​estrictamente garantizado que sea suficiente, aunque en la práctica presumiblemente debe ser lo mismo.
underscore_d
@underscore_d: sí, punto justo: unsigned long longse garantiza que sea de al menos 64 bits, pero en teoría size_tpodría ser más grande que esto, supongo. Por supuesto, si tiene> 2 ^ 64 elementos en su contenedor, entonces puede tener mayores problemas de los que preocuparse ... ;-)
Paul R
1

Creo que autoes bueno cuando se usa en un contexto localizado, donde el lector puede deducir fácilmente su tipo, o bien documentado con un comentario de su tipo o un nombre que infiera el tipo real. Aquellos que no entienden cómo funciona pueden tomarlo de manera incorrecta, como usarlo en lugar de hacerlo templateo similar. Aquí hay algunos casos de uso buenos y malos en mi opinión.

void test (const int & a)
{
    // b is not const
    // b is not a reference

    auto b = a;

    // b type is decided by the compiler based on value of a
    // a is int
}

Buenos usos

Iteradores

std::vector<boost::tuple<ClassWithLongName1,std::vector<ClassWithLongName2>,int> v();

..

std::vector<boost::tuple<ClassWithLongName1,std::vector<ClassWithLongName2>,int>::iterator it = v.begin();

// VS

auto vi = v.begin();

Punteros de funciones

int test (ClassWithLongName1 a, ClassWithLongName2 b, int c)
{
    ..
}

..

int (*fp)(ClassWithLongName1, ClassWithLongName2, int) = test;

// VS

auto *f = test;

Malos usos

Flujo de datos

auto input = "";

..

auto output = test(input);

Firma de función

auto test (auto a, auto b, auto c)
{
    ..
}

Casos triviales

for(auto i = 0; i < 100; i++)
{
    ..
}
Khaled.K
fuente
Cuando quieres un int, tienes que escribir un carácter más si quieres auto. Eso es inaceptable
Rerito
@Rerito sí, es inttan fácil de ver aquí y escribir intes más corto. Por eso es un caso trivial.
Khaled.K
0

Me sorprende que nadie haya mencionado esto, pero supongamos que está calculando el factorial de algo:

#include <iostream>
using namespace std;

int main() {
    auto n = 40;
    auto factorial = 1;

    for(int i = 1; i <=n; ++i)
    {
        factorial *= i;
    }

    cout << "Factorial of " << n << " = " << factorial <<endl;   
    cout << "Size of factorial: " << sizeof(factorial) << endl; 
    return 0;
}

Este código generará esto:

Factorial of 40 = 0
Size of factorial: 4

Definitivamente ese no fue el resultado esperado. Eso sucedió porque autodedujo el tipo de variable factorial como intporque se le asignó 1.

xilpex
fuente