2012-06-23 17 views
29

Si quiero obtener un valor en el vector, puedo usar dos opciones: usar el operador []. O puede utilizar la función de .at ejemplo de uso:¿Por qué usar "vector.at (x)" es mejor que "vector [x]" en C++?

vector<int> ivec; 
ivec.push_back(1); 

ahora que puedo hacer ambas cosas

int x1 = ivec[0]; 
int x2 = ivec.at(0); // or 

oí utilizando por lo es una mejor opción porque cuando uso esa opción me puedo tirar esto uno en una excepción

¿Alguien puede explicar esto?

+3

"¿Cuál es la diferencia?" es una buena pregunta La respuesta es: 1) comprobación automática de rango (.at() arrojará una excepción fuera de rango, [] fallará en silencio), y 2) preferencia personal - qué sintaxis te gusta más. "¿Qué es mejor?", Por otro lado, es un juicio de valor. La respuesta es necesariamente "depende". En mi humilde opinión ... – paulsm4

+11

Nadie es mejor, tienen objetivos similares pero diferentes. –

Respuesta

54

La diferencia entre c[i] y c.at(i) es que at() tiros std::out_of_range excepción si i cae fuera del rango del vector, mientras que operator[] simplemente invoca un comportamiento indefinido, lo que significa que cualquier cosa puede pasar.

Nadie dice at() es mejor que operator[]. Solo depende de las circunstancias. Como at() realiza una comprobación de rango, puede que no sea siempre deseable, especialmente cuando el código en sí mismo asegura que el índice nunca puede quedar fuera del rango. En tales casos, operator[] es mejor.

Considere el siguiente bucle:

for(size_t i = 0 ; i < v.size(); ++i) 
{ 
    //Should I use v[i] or v.at(i)? 
} 

En tal circuito, operator[] es siempre una opción mejor en comparación con at() función miembro.

Preferiría at() cuando lo desee arrojar una excepción en caso de índice no válido, por lo que podría hacer el trabajo alternativo en el bloque catch{ ...}. excepciones ayudan a separar el código normal a partir del código excepcional/alternativo como:

try 
{ 
    size_t i = get_index(); //I'm not sure if it returns a valid index! 

    T item = v.at(i); //let it throw exception if i falls outside range 

    //normal flow of code 
    //... 
} 
catch(std::out_of_range const & e) 
{ 
    //alternative code 
} 

Aquí podrías comprobar i a sí mismo, para asegurarse de que es un índice válido, y luego llamar a operator[] en lugar de at(), pero mezclaría el código normal con el código alternativo usando el bloque if-else que hace que sea difícil leer el flujo normal del código. Si ve arriba, try-catch mejora la legibilidad del código, ya que realmente separa el código normal del código alternativo, lo que resulta en un código ordenado y limpio.

+4

"Nadie dice' at() 'is better" - ¡ja! Te sorprenderias. –

+0

@KonradRudolph: ¿Qué? – Nawaz

+7

No subestimes cuántos idiotas hay, y cuántos de ellos enseñan C++. ;-) –

10

La única diferencia entre at y [] es que at realiza una verificación de rango y [] no. Si ya ha revisado el rango o si ha construido su índice de manera tal que no puede salir del rango y necesita acceder a un elemento repetidamente, puede ahorrar algunos ciclos de CPU al optar por [] en lugar de at.

Ejemplo de un solo cheque y múltiples accesos:

size_t index = get_index(vect); 
if (index < 0 || index >= vect.size()) return; 
if (vect[index] > 0) { 
    // .... 
} else if (vect[index] > 5) { 
    // .... 
} else .... 

ejemplo de un caso cuando el índice está construido para ser límites dentro:

for (size_t i = 0 ; i != vect.size() ; i++) { 
    if (vect[i] > 42) { 
     // .... 
    } 
} 
0

Las otras respuestas son del todo correcta, pero puede dé la impresión de que es una buena idea usar at() al escribir código que aún estará depurando, ya que eso provocará un error. Este es el caso en general, pero no se aplica a los compiladores más extendidos: se puede configurar gcc para que realice comprobaciones de rango (fatales) por putting it in debug mode y algo similar probablemente se pueda hacer en Visual Studio.

0

El método vectorial C++ .at comprueba los límites, por lo tanto, cuando el elemento no existe en el vector y se lanza la excepción out_of_range.

Cuando se usa [] no se realiza ninguna comprobación en el vector, por lo tanto, si el elemento no existe, no se lanza ninguna excepción y el resultado es un comportamiento indefinido como tener valores aleatorios de elementos no ejecutables en el vector.

El uso de [] es mejor que at en términos de seguridad, sin embargo, esto requerirá más tiempo y tiene un impacto en la duración del programa.

Cuestiones relacionadas