125 votes

vector::at vs. vector::operator[]

Je sais que at() est plus lent que [] en raison de son contrôle des limites, qui est également abordé dans des questions similaires telles que Vitesse de l'opérateur C++ Vector at/[] ou ::std::vector::at() vs operator[] << résultats surprenants ! !! 5 à 10 fois plus lent/rapide ! . Je ne comprends pas ce que le at() La méthode est bonne pour.

Si j'ai un vecteur simple comme celui-ci : std::vector<int> v(10); et je décide d'accéder à ses éléments en utilisant at() au lieu de [] dans une situation où j'ai un indice i et je ne suis pas sûr que ce soit dans les limites des vecteurs, cela m'oblige à l'envelopper dans un bloc try-catch :

try
{
    v.at(i) = 2;
}
catch (std::out_of_range& oor)
{
    ...
}

bien que je sois capable d'obtenir le même comportement en utilisant size() et de vérifier l'index par moi-même, ce qui me semble plus facile et plus pratique pour moi :

if (i < v.size())
    v[i] = 2;

Donc ma question est :
Quels sont les avantages d'utiliser vecteur::at sur vecteur::opérateur[] ?
Quand dois-je utiliser vecteur::at plutôt que vecteur::taille + vecteur::opérateur[] ?

1voto

Rohit Points 2629

At est généralement utilisé avec assert pour valider les limites d'un tableau.

La différence entre cette fonction membre et l'opérateur membre de la fonction operator[] est que vector::at signale si la position demandée est hors de portée en lançant une exception out_of_range.

1voto

ltjax Points 11115

L'intérêt d'utiliser des exceptions est que votre code de gestion des erreurs peut être plus éloigné.

Dans ce cas précis, l'entrée de l'utilisateur est effectivement un bon exemple. Imaginons que vous souhaitiez analyser sémantiquement une structure de données XML qui utilise des indices pour faire référence à un type de ressource que vous stockez en interne dans un fichier de type std::vector . Maintenant, l'arbre XML est un arbre, donc vous voulez probablement utiliser la récursion pour l'analyser. Au plus profond de la récursion, il peut y avoir une violation d'accès par l'auteur du fichier XML. Dans ce cas, vous souhaitez généralement supprimer tous les niveaux de récursion et rejeter l'ensemble du fichier (ou toute autre structure plus "grossière"). C'est là qu'at se révèle utile. Vous pouvez simplement écrire le code d'analyse comme si le fichier était valide. Le code de la bibliothèque s'occupera de la détection des erreurs et vous pourrez simplement attraper l'erreur au niveau grossier.

De plus, d'autres conteneurs, comme std::map , ont également std::map::at qui a une sémantique légèrement différente de celle de std::map::operator[] : at peut être utilisé sur une carte const, alors que operator[] pas. Maintenant, si vous vouliez écrire du code agnostique pour les conteneurs, comme quelque chose qui pourrait traiter avec soit const std::vector<T>& o const std::map<std::size_t, T>& , ContainerType::at serait votre arme de choix.

Cependant, tous ces cas apparaissent généralement lors du traitement d'une entrée de données non validée. Si vous êtes sûr de votre plage de validité, comme vous devriez l'être, vous pouvez généralement utiliser operator[] mais mieux encore, les itérateurs avec begin() y end() .

1voto

ahj Points 167

Según este article, les performances mises à part, cela ne fait aucune différence d'utiliser at o operator[] seulement si l'accès est garanti dans les limites de la taille du vecteur. Sinon, si l'accès est simplement basé sur la capacité du vecteur, il est plus sûr d'utiliser at .

0voto

ShitalShah Points 2213

Nota: Il semblerait que certains nouveaux venus descendent cette réponse sans avoir la courtoisie de dire ce qui est faux. La réponse ci-dessous est correcte et peut être vérifiée aquí .

Il n'y a vraiment qu'une seule différence : at fait la vérification des limites tandis que operator[] ne le fait pas. Cela s'applique aussi bien aux builds de débogage qu'aux builds de publication et cela est très bien spécifié par les normes. C'est aussi simple que cela.

Cela rend at une méthode plus lente mais c'est aussi un très mauvais conseil de ne pas utiliser at . Il faut regarder les chiffres absolus, pas les chiffres relatifs. Je peux parier sans risque que la plupart de votre code effectue des opérations beaucoup plus coûteuses que at . Personnellement, j'essaie d'utiliser at car je ne veux pas qu'un méchant bogue crée un comportement indéfini et se glisse dans la production.

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