Pour leur donne-t-on le nom de conteneurs associatifs ?
Une map ou une multimap associe bien une clef à un élément, mais un set est juste un ensemble trié ? Pourquoi l'affubler du nom d'associatif ?
Merci.
Version imprimable
Pour leur donne-t-on le nom de conteneurs associatifs ?
Une map ou une multimap associe bien une clef à un élément, mais un set est juste un ensemble trié ? Pourquoi l'affubler du nom d'associatif ?
Merci.
C'est juste un cas de particulier de conteneur associatif où la clé et l'élément sont confondus. Mais à part ça, cela ne diffère en rien d'un autre conteneur associatif tel que std::map.
Ok, je reste un peu sur ma faim, mais je comprends à peu près.
Dans le set, les clés sont portés par les objets eux-même. Ils en possèdent déjà une. Par contre, comme tu le sais déjà, la map introduit une clé externe pour chaque élément.
J'ignorais que les set étaient appelés "associatifs"... Et je dois dire que j'en suis surpris aussi.
Si je peux rajouter une question allant dans le même sens : quelqu'un sait t'il s'il y a un ancêtre commun à la map et au set au sens héritage définit dans la STL ? Quelque chose qui pourrait s'appeler AssociativeContainer et duquel hériterait les deux containers ?
Qui a la réponse répond à la question initiale...
Non, il n'y a pas d'héritage entre conteneurs de la STL. La généricité de la STL n'est pas gérée par une interface au sens POO, mais par un concept (non explicitable dans le code actuellement :( ) au sens template.
Pour la question initiale, set est une conteneur associatif parce que c'est comme ça, faut pas chercher à comprendre, circulez, ya rien à voir ;)
Tu vois peut-être une map<K, D> comme associant une donnée D à la clef K :
mais c'est plus le point de vue de operator[].Code:
1
2
3 void f (std::map<K, D> &m, K k) { D d = m[k]; }
Une map associe un élément à une clef : map<K, D>::element_type étant défini comme pair<const K, D>, map associe pair<const K, D> à K. C'est l'opération effectuée par find, qui est l'opération cruciale (je n'ose dire "opération clef") :
find (k)->first = k
Un set associe K à K :
*find (k) = k
En fait, les deux sont généralement implémentés en terme de rbtree<K, E, Pi>, qui associe un E à K, avec Pi : E -> K, tel que :
Pi()(*find (k)) = k
ce qui permet naturellement de définir set<K> à partir de
rbtree<K, K, Id>(où Id() est l'identité)
et map<K, D> à partir de
rbtree<K, pair<const K, D>, First>(avec First()(x) = x.first)
Bien sûr, j'ai simplifié, il y a aussi le comparateur à passer, et un paramètre pour choisir entre conteneur à clef unique (set, map) et conteneur à clef multiples (multiset, multimap).
Les hash_(multi)set/map sont définis pareil, en terme de hashtable<K,E,Pi,etc.>
Malheureusement, rien de tout ça n'est standard, et on doit supporter l'insupportable interface de set et compagnie, garantie "sure pour les bébés".