29 votes

Pourquoi utiliser le "vecteur.au(x)" mieux que "vecteur[x]" en C++?

Si je veux obtenir une valeur dans le vecteur je peux utiliser deux options : utiliser l'opérateur []. Ou je pourrais utiliser la fonction .à l'exemple d'utilisation :

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

Maintenant, je peux faire deux choses

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

J'ai entendu à l'aide d'au est une meilleure option, car lorsque j'utilise cette option, je peux jeter celui-ci dans une exception.

Quelqu'un peut-il m'expliquer pourquoi? Merci à l'avance. Gili

54voto

Nawaz Points 148870

La différence entre c[i] et c.at(i) que at() jette std::out_of_range exception si i tombe en dehors de la plage du vecteur, alors que operator[] invoque simplement un comportement indéfini, ce qui signifie que tout peut arriver.

Personne ne dit at() est mieux que operator[]. Ça dépend des circonstances. En tant que at() effectue le contrôle de portée, il peut ne pas être souhaitable toujours, en particulier lorsque votre code en lui-même permet de s'assurer que l'index ne peut jamais tomber en dehors de la plage. Dans de tels cas, operator[] , c'est mieux.

Considérons la boucle suivante:

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

Dans une telle boucle, operator[] est toujours un meilleur choix en comparaison à d' at() de la fonction membre.

Je préfère at() quand je veux lancer une exception dans le cas d'index non valide, de sorte que je pourrais en faire un autre travail dans l' catch{ ...} bloc. Les Exceptions permettent de séparer le code de l'exceptionnelle/code alternatif comme:

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
}

Ici vous pouvez cocher la case i vous-même, assurez-vous qu'il est un index valide, puis appelez operator[] au lieu de at(), mais qu'il serait mélanger le code avec le code alternatif à l'aide de if-else bloc qui le rend difficile à lire le flux normal de code. Si vous voyez ci-dessus, try-catch améliore la lisibilité du code, comme il vraiment sépare le code de la code alternatif, résultant dans un cadre soigné et propre code.

10voto

dasblinkenlight Points 264350

La seule différence entre at et [] que at effectue un contrôle de portée, et [] ne le sont pas. Si vous avez coché la gamme déjà ou avez construit votre index de telle manière qu'il ne peut pas sortir de gamme, et ont besoin d'accéder à un élément à plusieurs reprises, vous pourriez économiser quelques cycles CPU en optant pour [] au lieu d'un at.

Exemple d'un seul de vérifier et d'accès multiples:

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

Exemple d'un cas où l'indice est construit à l'intérieur des limites:

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

0voto

Anton Golov Points 1953

Les autres réponses sont tout à fait correct, mais il peut donner l'impression que c'est une bonne idée d'utiliser at() lors de l'écriture de code que vous serez toujours le débogage, car cela provoquera une erreur à signaler. C'est le cas en général, mais ne s'applique pas pour la plus répandue compilateurs gcc -- peut exécuter (fatale) de la gamme des vérifications pour le mettre en mode debug, et quelque chose de semblable peut probablement être fait dans Visual Studio.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X