Je ne suis pas très fan de la division non plus. Une postcondition non respectée, c’est une erreur de programmation. Et là: deux approches: assertion (ou [[expect: ]]
en C++20), ou TU.
Les exceptions, c’est pour des cas indépendants de notre volonté. Je ne les mettrai pas au milieu de calculs (hors cas où il est moins cher de vérifier en cours de route comme des inversions de matrices), mais en amont: vérification des entrées externes au binaire en cours d’exécution.
Les itérateurs ne bouclent pas. Mais c’est un machin que l’on utilise pour itérer sur les éléments du collection dans des structures de contrôle de type boucle. On (nous!) boucle sur des éléments en déplaçant un curseur. Ce curseur peut être modélisé via un itérateur ou un index. Dans ce §, on aborde les itérateurs.
Effectivement, point important des itérateurs du standard C++: ils pointent sur des éléments là où les itérateurs du GoF, d’autres langages ou d’autres frameworks pointent entre deux éléments.
Grâce au C++11, on n’a pratiquement plus jamais besoin d’exprimer le type exact d’un itérateur. C’est ici l’endroit idéal pour introduire auto
ou les for range-loop. Saute la partie qui permet d’avoir un itérateur qui ne référence rien, de toute façon, c’est une mauvaise pratique. Ne leur montre pas comment avoir des itérateurs dans le vide, ou alors pour mettre une note qui dise que c’est certainement une mauvaise idée.
end()
, c’est la position au delà du dernier élément.
Après, travailler sur des plages semi-ouvertes (ou semi-fermées), c’est la façon type en C (où on itère entre 0 et N-1 en testant != N
, ou < N
. Ca marche très bien pour les itérateurs qui pointent sur des éléments (et non entre). Et surtout, c’est la façon la plus simple pour exprimer des plages vides.
Tous les conteneurs fournissent aussi l’opération inverse
Non. Il m’est facile d’en écrire un qui ne soit pas bi-directionnel. Beaucoup de BDs qui sont des surcouches simples à fichiers, ne sont que forward d’ailleurs. Mieux: std::forward_list<>
conteneurs à accès aléatoire
En VF, on dit "à accès direct".
Heureusement, la bibliothèque standard est bien fournie
Attention, cela ne veut pas dire que cela doit être utilisé. Parfois, c’est nécessaire, mais il y a probablement une meilleure façon de travailler.
Je me souviens d’une implémentation de bibliothèque type STL de Roguewave qui offrait un list::operator[]()
. Devine le genre de code que j’avais vu:
| for (int i=0; i != liste.size() ; ++i)
do_stuff(liste[i]);
|
Ou comment améliorer facilement les perfs d’un bout de code.... => quand on a des séquence chainées, il faut oublier les index et basculer à 100% sur des itérateurs -> une fonction de recherche doit renvoyer un itérateur et non un index, une fonction de retrait doit retirer un élément via un itérateur direct vers l’élément à retirer et non un numéro d’index, etc.
Bref, ces fonctions peuvent avoir un intérêt pour écrire des algorithmes génériques. Avant un tel chapitre dans ton cours, je n’en parlerai même pas.