2010-08-08 12 views
21

he visto código que utilizan vectores,Uso de la palabra clave auto en C STL ++

vector<int>s; 
s.push_back(11); 
s.push_back(22); 
s.push_back(33); 
s.push_back(55); 
for (vector<int>::iterator it = s.begin(); it!=s.end(); it++) { 
    cout << *it << endl; 
} 

Es igual que

for (auto it = s.begin(); it != s.end(); it++) { 
    cout << *it << endl; 
} 

¿Qué tan seguro es en este caso el uso de la palabra clave auto? ¿Y qué pasa si el tipo de vector es float? string?

Respuesta

38

auto palabra clave auto simplemente le pide al compilador que deduzca el tipo de la variable desde la inicialización.

Incluso un compilador anterior a C++ 0x sabe cuál es el tipo de una expresión (de inicialización), y la mayoría de las veces, puede ver ese tipo en los mensajes de error.

#include <vector> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    vector<int>s; 
    s.push_back(11); 
    s.push_back(22); 
    s.push_back(33); 
    s.push_back(55); 
    for (int it=s.begin();it!=s.end();it++){ 
     cout<<*it<<endl; 
    } 
} 

Line 12: error: cannot convert '__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*, __gnu_norm::vector<int, std::allocator<int> > >, __gnu_debug_def::vector<int, std::allocator<int> > >' to 'int' in initialization 

El auto palabra clave simplemente le permite tomar ventaja de este conocimiento - si (compilador) conoce el tipo correcto, acaba de elegir para mí!

+0

estoy utilizando Visual C++ 2010 por lo que mi compilador no tiene ningún problema con la palabra clave auto –

+0

buena explicación. +1 – jalf

+3

Especialmente me gusta que 'auto' es * heluvalot * más corto que el tipo real. –

11

La palabra clave auto obtiene el tipo de la expresión a la derecha de =. Por lo tanto, funcionará con cualquier tipo, el único requisito es inicializar la variable automática al declararlo para que el compilador pueda deducir el tipo.

Ejemplos:

auto a = 0.0f; // a is float 
auto b = std::vector<int>(); // b is std::vector<int>() 

MyType foo() { return MyType(); } 

auto c = foo(); // c is MyType 
+10

Aunque técnicamente correcta. Espero que esto se convierta en una mala práctica. Si todo el mundo declara todas sus variables como "automáticas", a los humanos les resultará difícil leer y comprender (y nos dirigiremos a los idiomas no tipificados). El uso de autos debe reservarse para situaciones en las que en realidad no se preocupan por el tipo, siempre que se comporta de una casa que queremos (por ejemplo, iteradores, que no les importa lo que realmente iterador que obtenemos como el tiempo que podamos úsalo como un iterador). –

+1

@Martin: No es broma, la primera vez que vi un bloque de variables 'auto' pensé "por favor mueren rápido". Como dijiste, debería usarse en ese tipo de situaciones "Dame una variable, sea del tipo que sea", no es que "declare una variable, y deduzca su tipo desde su inicializador jejejeje". tratando de ser una mierda difícil. – GManNickG

+0

@sverkerw: No. Quiero decir que es difícil para los humanos leer. ¿Cuál es el tipo de c? Necesito saber ¿Cómo afecta mi interpretación del resto del código? –

3

auto palabra clave tiene la intención de utilizar en tal situación, es absolutamente seguro. Pero lamentablemente está disponible solo en C++ 0x, por lo que tendrá problemas de portabilidad.

21

Es información adicional, y no es una respuesta. Pero ya que no tengo la reputación suficiente como para comentar, sólo puede escribir aquí:

En C++ 11 puede escribir:

for (auto& it : s) { 
    cout << it << endl; 
} 

en lugar de

for (auto it = s.begin(); it != s.end(); it++) { 
    cout << *it << endl; 
} 

Tiene el mismo significado.

Actualización: Consulte el comentario de @ Alnitak también.

+12

esos no son equivalentes - en el primero, la variable 'it' es del tipo' value_type' y no es realmente un iterador. – Alnitak

+0

Reemplazaría 'std :: endl' con' "\ n" 'en este caso, evitando la operación de descarga. [motivación] (https://stackoverflow.com/questions/213907/c-stdendl-vs-n) – JHBonarius

2

Este es un nuevo elemento en el idioma que creo que vamos a tener problemas en los próximos años. El 'auto' de inicio presenta no solo un problema de legibilidad, de ahora en adelante, cuando lo encuentre, tendrá que pasar un tiempo considerable tratando de descubrir cuál es (al igual que el tiempo que el interno nombró a todas las variables xyz :)), pero también pasarás un tiempo considerable limpiando después de programadores fácilmente excitables, como el que respondió antes que yo. Ejemplo de lo anterior, puedo apostar $ 1000, se escribirá "para (auto: s)", no "para (auto & it: s)", como resultado invocando la semántica de movimiento donde lo hace esperar, modificando su colección debajo.

Otro ejemplo del problema es su pregunta en sí.Claramente no sabe mucho acerca de los iteradores STL y que intenta superar esa brecha a través del uso de la magia de 'auto', como resultado de crear el código que podría ser problemático más adelante