La palabra clave auto en C++ (desde C++11) permite que el compilador infiera automáticamente el tipo de una variable a partir de la expresión de inicialización. Esto simplifica el trabajo con tipos largos (por ejemplo, al trabajar con iteradores, lambdas, expresiones de plantillas) y mejora la legibilidad del código.
Ejemplo de uso:
auto i = 42; // int auto d = 3.14; // double auto s = std::string("hi"); auto it = v.begin(); // iterador
Sin embargo, auto infiere el tipo exactamente según lo que se le "da". Por ejemplo, si se devuelve por valor, auto dará un valor, pero si se devuelve por referencia — una referencia. Se debe tener cuidado al trabajar con referencias, punteros y calificaciones const.
Ejemplo importante:
std::vector<int> v = {1,2,3}; for (auto x : v) x = 0; // copia, v no cambiará for (auto& x : v) x = 0; // referencia, los elementos se establecerán a cero
¿Qué tipo tendrá la variable 'z' en la expresión
const auto z = foo();si el métodofoo()devuelve una referencia a int (int&)?
Respuesta:
const auto z inferirá el tipo como int (valor), incluso si se devuelve una referencia. Para inferir una referencia, se necesita auto& z. Los calificadores const se aplican al tipo auto después de la inferencia del tipo.
Ejemplo:
int x = 5; auto a = x; // a — int auto& b = x; // b — int& const auto c = x; // c — const int auto d = foo(); // d — int (si foo devuelve int) auto& e = foo(); // e — int&
Historia
En un gran servicio web, se utilizó un bucle basado en rangos con auto en lugar de auto& sobre una colección de punteros inteligentes. Esto llevó a la copia de objetos, lo que ralentizaba el programa 16 veces al procesar millones de registros.
Historia
En una biblioteca de trabajo con gráficos, se aplicó auto al iterador devuelto, esperando que fuera una referencia, pero obtuvieron un objeto temporal. El iterador se destruyó prematuramente, después del ciclo el programa caía en UB.
Historia
En un sistema financiero, debido al uso de auto para obtener un valor de un mapa, se olvidaron de la constancia de la clave, lo que llevó a un intento de modificar datos a través de una referencia no constante y a errores de compilación y caídas en tiempo de ejecución.