2011-09-28 19 views
90

De todo el material que utilicé para aprender C++, auto siempre ha sido un especificador de duración de almacenamiento extraño que no sirvió para nada. Pero hace poco, me encontré con un código que lo usaba como un nombre de tipo en sí mismo. ¡Por curiosidad lo intenté, y asume el tipo de lo que sea que le asigne!Palabra clave auto de C++. ¿Por qué es magia?

De repente, los iteradores de STL y, bueno, cualquier cosa que use plantillas es 10 veces más fácil de escribir. Parece que estoy usando un lenguaje "divertido" como Python.

¿Dónde ha estado esta palabra clave toda mi vida? ¿Destruirá mis sueños diciendo que es exclusivo de Visual Studio o no portátil?

+10

no lo es. magia. Es nuevo (_oh noes, que mal pun_). Ahora async es el futuro (_gasp_) – sehe

+1

Aquí está la referencia sobre palabras clave automáticas http: //en.cppreference.com/w/cpp/language/auto – andyqee

Respuesta

80

auto era una palabra clave que C++ "heredaba" de C que había estado ahí casi para siempre, pero prácticamente nunca se usaba porque solo había dos condiciones posibles: o no estaba permitido, o bien se asumía de manera predeterminada.

El uso de auto para significar un tipo deducido es nuevo con C++ 11 (anteriormente llamado C++ 0x). Dado que el estándar C++ 11 se publicó muy recientemente, aún puede haber algunos compiladores que no se han actualizado para comprenderlo (todavía).

Al mismo tiempo, auto x funciona más o menos de la misma manera que la deducción de tipo de plantilla funciona para plantillas de funciones. Considere una plantilla de función como esta:

template<class T> 
int whatever(T t) { 
    // point A 
}; 

En el punto A, un tipo ha sido asignado a T basado en el valor pasado para el parámetro a whatever. Cuando lo hace auto x = some_expression;, esencialmente el mismo mecanismo de deducción de tipo se utiliza para determinar el tipo de x del tipo de some_expression que se utiliza para inicializarlo.

Esto significa que la mayoría de las mecánicas de deducción de tipo que necesita un compilador para implementar auto ya están presentes y se usan para plantillas en cualquier compilador que incluso intenta implementar C++ 98/03. Como tal, incluso para aquellos compiladores que aún no son compatibles con C++ 11, agregar soporte para auto probablemente sea bastante rápido y fácil.

Cuando esta respuesta se escribió originalmente (en 2011, antes de que la tinta estuviera seca en el estándar C++ 11) auto ya era bastante portátil. Hoy en día, es totalmente portátil entre todos los compiladores convencionales. Las únicas razones obvias para evitarlo serían si necesita escribir código que sea compatible con un compilador de C, o si tiene una necesidad específica de apuntar a un compilador de nicho que sepa que no lo admite (p. Ej., Algunas personas todavía escriben código). para MS-DOS utilizando compiladores de Borland, Watcom, etc., que no han visto mejoras significativas en décadas).

10

Esta funcionalidad no ha estado allí toda su vida. Se ha admitido en Visual Studio desde la versión de 2010. Es una nueva característica de C++ 11, por lo que no es exclusiva de Visual Studio y es/será portátil. La mayoría de los compiladores ya lo soportan.

18

Simplemente toma una palabra clave generalmente inútil y le da una nueva y mejor funcionalidad. Es estándar en C++ 11, y la mayoría de los compiladores C++ incluso con algún soporte C++ 11 lo admitirán.

+0

¡Oh! Ajá, nunca pensó en C++ el lenguaje como algo que podría cambiar por sí mismo. Voy a tener que buscar qué más agregaron en este C++ 11, escuché un poco de C++ 0x pero nunca profundicé demasiado en él. –

+6

@Clairvoire C++ 0x era el nombre provisional. Se ha publicado este mes y, por lo tanto, se convirtió en C++ 11. –

3

No va a ninguna parte ... es una nueva característica estándar de C++ en la implementación de C++ 11. Dicho esto, si bien es una herramienta maravillosa para simplificar declaraciones de objetos, así como para limpiar la sintaxis de ciertos paradigmas de llamada (es decir, bucles for-basados ​​basados ​​en rangos), no lo use en exceso ni abuse de él :-)

5

Para variables, especifica que el tipo de la variable que se está declarando se deducirá automáticamente de su inicializador. Para funciones, especifica que el tipo de devolución es un tipo de devolución final o se deducirá de sus declaraciones de devolución (ya que C++ 14).

Sintaxis

auto variable initializer (1) (since C++11) 

auto function -> return type (2) (since C++11) 

auto function (3) (since C++14) 

decltype(auto) variable initializer (4) (since C++14) 

decltype(auto) function (5) (since C++14) 

auto :: (6) (concepts TS) 

cv(optional) auto ref(optional) parameter (7) (since C++14) 

Explicación

1) Cuando la declaración de variables en ámbito de bloque, en el perímetro de espacio de nombres, en los estados de inicialización de los bucles, etc., el automóvil se puede utilizar la palabra clave como el especificador de tipo. Una vez que se ha determinado el tipo de inicializador, el compilador determina el tipo que reemplazará la palabra clave auto utilizando las reglas para la deducción de argumento de plantilla desde una llamada a función (ver deducción del argumento de plantilla # Otros contextos para más detalles). La palabra clave auto puede ir acompañada de modificadores, como const o &, que participarán en la deducción del tipo. Por ejemplo, dado const auto& i = expr;, el tipo de i es exactamente el tipo del argumento u en una plantilla imaginaria template<class U> void f(const U& u) si se compiló la llamada a la función f(expr). Por lo tanto, auto & & se puede deducir como una referencia lvalue o una referencia rvalue según el inicializador, que se utiliza en el bucle for-based. Si se usa auto para declarar múltiples variables, los tipos deducidos deben coincidir. Por ejemplo, la declaración auto i = 0, d = 0.0; está mal formada, mientras que la declaración auto i = 0, *p = &i; está bien formada y el auto se deduce como int.

2) En una declaración de función que utiliza la sintaxis del tipo de retorno final, la palabra clave auto no realiza la detección automática de tipo. Solo sirve como parte de la sintaxis.

3) En una declaración de función que no utiliza la sintaxis de tipo de retorno final, la palabra clave auto indica que el tipo de retorno se deducirá del operando de su declaración de devolución utilizando las reglas para la deducción de argumentos de plantilla.

4) Si el tipo declarado de la variable es decltype (auto), la palabra clave auto se reemplaza con la expresión (o lista de expresiones) de su inicializador, y el tipo real se deduce usando las reglas para decltype.

5) Si el tipo de devolución de la función se declara decltype (auto), la palabra clave auto se reemplaza con el operando de su declaración de devolución, y el tipo de devolución real se deduce usando las reglas para decltype.

6) Un especificador de nombre anidado de la forma auto :: es un marcador de posición que se reemplaza por una clase o tipo de enumeración siguiendo las reglas para la deducción de marcador de posición de tipo restringido.

7) Una declaración de parámetro en una expresión lambda. (desde C++ 14) Una declaración de parámetro de función. (conceptos TS)

Notas Hasta C++ 11, auto tuvieron la semántica de un especificador de duración del almacenamiento. No está permitido mezclar variables automáticas y funciones en una declaración, como en auto f() -> int, i = 0;.

Para más información: http://en.cppreference.com/w/cpp/language/auto

+1

Probablemente deberías usar bloques de código para los ejemplos de código – KABoissonneault

Cuestiones relacionadas