Collections et boucle for each

Quelques exemples de collections

Rappel: tableaux (vector)

Nous avons vu qu’un tableau (vector en C++) regroupe plusieurs valeurs dans un ordre donné, en tenant compte des répétitions:

#include<vector>
using namespace std;
vector<int> v = { 3, 2, 5, 2 };
v

Cela donne un sens au i-ème élément d’un tableau:

v[3]

Un tableau est un exemple de valeur composite homogène, ou collection qui regroupe plusieurs valeurs d’un même type.

Il existe d’autres types de collections. Voyons quelques exemples.

Ensembles (set)

Lorsque l’on souhaite ne tenir compte ni de l’ordre, ni des répétitions – comme dans un ensemble mathématique – on peut utiliser un set:

#include <set>
using namespace std;
set<int> s = { 3, 2, 5, 2};
s

Du coup, accéder au i-ème élément n’a pas de sens:

s[1]

Multi-ensembles (multiset)

Si l’on ne souhaite pas tenir compte de l’ordre mais tout de même des répétitions, on peut utiliser un multi-ensemble (multiset):

multiset<int> m = { 3, 2, 5, 2 };
m

Boucle foreach

Une opération omniprésente sur une collection est de parcourir toutes ses valeurs: jusqu’ici on l’a fait à l’aide d’un index:

#include<vector>
#include<iostream>
using namespace std;
vector<int> v = { 3, 2, 5, 2 };
for ( int i=0; i < v.size(); i++ )
    cout << v[i] << endl;

C’est un peu lourd, et sujet à erreurs. Surtout, cela ne se généralisera pas aux ensembles! (pourquoi?).

À la place nous allons litérallement écrire «pour toute valeur dans v faire …»:

for ( auto valeur: v )
    cout << valeur << endl;

C’est l’équivalent du for valeur in v: de Python. Et cela fonctionnera tout aussi bien pour toute autre collection:

#include<set>
set<int> s = { 3, 2, 5, 2 };
for ( auto valeur: s )
    cout << valeur << endl;
multiset<int> m = { 3, 2, 5, 2 };
for ( auto valeur: m )
    cout << valeur << endl;

Digression: à propos de auto

Vous vous demandez peut-être quelle est la signification de auto?

On est en train de déclarer une nouvelle variable. Il faut donc préciser son type. On pourrait très bien mettre int ci-dessus puisque l’on manipule des collections d’entiers:

for ( int valeur: v )
    cout << valeur << endl;

auto est un type spécial qui indique à C++ de sélectionner automatiquement le type adéquat en fonction du contexte ce qui est facile ici.

auto i = 1;
i
auto pi = 3.14;
pi