Qu'est-ce qui est si bien dans la STL ?
La STL a la particularité d'avoir été conçue très tôt et d'avoir réussi à utiliser le paradigme de la programmation générique C++ de manière très efficace.
Il a séparé efficacement les structures de données : vector
, map
... et les algorithmes pour les exploiter. copy
, transform
... en profitant des modèles pour le faire.
Il découple proprement les préoccupations et fournit des conteneurs génériques avec des crochets de personnalisation ( Comparator
y Allocator
paramètres du modèle).
Le résultat est très élégant (principe DRY) et très efficace grâce aux optimisations du compilateur, de sorte que les algorithmes générés à la main pour un conteneur donné ont peu de chances de faire mieux.
Cela signifie également qu'il est facilement extensible : vous pouvez créer votre propre conteneur avec l'interface que vous souhaitez, tant qu'il expose des itérateurs conformes à la STL, vous pourrez utiliser les algorithmes de la STL avec lui !
Et grâce à l'utilisation de traits, vous pouvez même appliquer les algorithmes sur des tableaux C par le biais de simples pointeurs ! Vous parlez de rétrocompatibilité !
Cependant, il aurait pu (peut-être) être meilleur...
Qu'est-ce qui n'est pas si bien dans la STL ?
Cela m'énerve vraiment que l'on doive toujours utiliser les itérateurs, je supporterais vraiment de pouvoir écrire : std::foreach(myVector, [](int x) { return x+1;});
parce qu'il faut bien l'admettre, la plupart du temps, on veut itérer sur l'ensemble du conteneur...
Mais ce qui est pire, c'est qu'à cause de ça :
set<int> mySet = /**/;
set<int>::const_iterator it = std::find(mySet.begin(), mySet.end(), 1005); // [1]
set<int>::const_iterator it = mySet.find(1005); // [2]
[1]
y [2]
sont effectuées de manière totalement différente, ce qui donne [1]
ayant une complexité O(n) alors que [2]
a une complexité O(log n) ! Ici, le problème est que les itérateurs font trop d'abstraction.
Je ne veux pas dire que les itérateurs n'ont pas de valeur, je veux simplement dire que fournir une interface exclusivement en termes d'itérateurs était un mauvais choix.
Je préfère de loin l'idée de vues sur les conteneurs, par exemple, regardez ce qui a été fait avec Boost.MPL . Avec une vue, vous manipulez votre conteneur avec une couche (paresseuse) de transformation. Cela donne des structures très efficaces qui vous permettent de filtrer certains éléments, d'en transformer d'autres etc...
Combinaison de vues y vérification des concepts Je pense que ces idées produiraient une bien meilleure interface pour les algorithmes STL (et résoudraient le problème de l'utilisation de ces algorithmes). find
, lower_bound
, upper_bound
, equal_range
).
Cela permettrait également d'éviter les erreurs courantes d'utilisation de plages d'itérateurs mal définies et le comportement indéfini qui en résulte...