Comment l'algorithme STL fonctionne-t-il indépendamment du type Iterator?Comment l'algorithme STL fonctionne-t-il indépendamment du type Iterator?
Répondre
Vraiment, ils fonctionnent juste. Ils utilisent des propriétés assez simples de modèles, parfois appelés polymorphisme statique. Si vous connaissez le terme, c'est essentiellement une forme de ducktyping. (Si ça ressemble à un canard, et ça se transforme en un canard, ça doit être un canard)
L'astuce est simple. Voici un exemple très simple:
template <typename T>
void say_hello(const T& t) {
t.hello();
}
La fonction say_hello
ne se soucie pas de quel type de son argument est. Il ne doit pas dériver d'une interface ou faire d'autres sortes de «promesses» sur ce que c'est. Tout ce qui compte, c'est que le type fonctionne dans ce contexte. Tout ce que nous faisons avec le type est appelez sa fonction hello
. Ce qui signifie que ce code sera compilé pour tout type qui a une fonction membre hello
.
Les algorithmes STL fonctionnent de manière similaire. Voici une implémentation simple de std::for_each
:
template <typename iter_type, typename func_type>
void for_each(iter_type first, iter_type last, func_type f){
for (iter_type cur = first; cur != last; ++cur) {
f(*cur);
}
}
Ce code compilera chaque fois que les types de modèle à la hauteur des exigences qui leur sont imposées; iter_type
doit avoir l'opérateur ++-pre-increment. Il doit avoir un constructeur de copie, et il doit avoir l'opérateur! =, Et il doit avoir l'opérateur * -dereference-operator.
func_type
doit mettre en œuvre l'opérateur d'appel de fonction, en prenant un argument du même type que vous obtenez par déréférencement un objet de type iter_type
. Si j'appelle for_each
avec des types qui satisfont ces exigences, le code compilera. iter_type
peut être n'importe quel type qui répond à ces exigences. Il n'y a rien dans le code qui dise "cela fonctionnera avec les itérateurs de vecteurs et les itérateurs de liste et les itérateurs de cartes". Mais tant que les itérateurs de vecteurs, de listes ou de cartes implémenteront les opérateurs que nous utilisons, cela fonctionnera.
Chaque itérateur est-il dérivé d'une interface commune? – yesraaj
non, il n'utilise pas l'héritage, ou ce qui est "habituellement" appelé polymorphisme. Les modèles permettent ce qu'on appelle parfois le "polymorphisme statique", sur lequel s'appuie le STL. Mais cela n'a rien à voir avec l'héritage, les interfaces ou les fonctions virtuelles. – jalf
Cette réponse est correcte. Le downvoter devrait rétracter leur vote, parce qu'ils ont besoin de lire un peu plus. –
Chaque algorithme STL est une fonction de modèle qui prend le type d'itération en tant que paramètre de modèle.
Tout algorithme STL est généré automatiquement par le compilateur pour chaque type d'itérateur avec lequel vous l'utilisez.
Il est appelé modèles C++ ou polymorphisme statique.
Les algorithmes STL sont des fonctions de modèle, ce qui signifie qu'ils peuvent être appelés avec n'importe quel type.
Lorsque vous appelez la fonction avec un type spécifique, le compilateur va essayer de compiler une instance de la fonction de ce type et signaler toute erreur de compilation (méthodes manquantes, des erreurs de contrôle de type, etc.)
STL algorithmes, tant que le type utilisé se comporte comme un itérateur (supporte ++, déréférencement), cela fonctionnera. C'est pourquoi ces algorithmes fonctionnent aussi avec des pointeurs natifs, car ils supportent le même type d'opérations que les itérateurs (c'est ainsi qu'ils ont été conçus en premier lieu).
Tous les algorithmes de conteneur/itérateur STL n'ont pas cette indépendance. Ceux qui le font s'appellent des algorithmes génériques, mais ceux-ci sont habituellement juste appelés des algorithmes de STL.
Avec itérateurs seulement vous pouvez:
- inspecter la séquence de sorte que vous pouvez faire des choses comme trouver, compter, for_each, ...
- changement la valeur des références iterator afin que vous puissiez faire des choses comme transformer, copier, faire pivoter, échanger, remplacer, ...
- réorganiser les valeurs des itérateurs, de sorte que vous pouvez faire des choses comme tri, fusion, nth_element.
Certains algorithmes non génériques peuvent être décomposés en 2 étapes, une partie LIST générique et une partie dépendant du conteneur. Donc, afin de détruire toutes les valeurs supérieures à 7 dans un vecteur, nous pouvons faire un remove_if (la partie générique qui ne fait que trier les éléments) suivi d'un effacement (la partie non générique qui détruit la valeur).
- 1. STL Iterator sans initialisant il
- 2. STL iterator avec modèle personnalisé
- 3. Retour d'un Iterator
- 4. Iterator externe vs Iterator interne
- 5. Bonne bibliothèque de type STL pour C
- 6. Iterator personnalisé en C++
- 7. La carte STL sur elle-même?
- 8. Conversion Enumeration à iterator
- 9. Comment faire une itération arrière dans une liste STL?
- 10. Comment vérifier si l'itérateur STL pointe sur quelque chose?
- 11. STL comme conteneur typedef raccourci?
- 12. Problèmes conceptuels avec Iterator
- 13. scala tourner un Iterator [Option [T]] dans un Iterator [T]
- 14. Liste Iterator Remove()
- 15. Utilisation du port STL dans VS2008
- 16. Comment utiliser SGI STL hash_map?
- 17. Obtenir l'Iterator pour un conteneur STL interne?
- 18. comment déclarer iterator volatile en C++
- 19. Iterator & Exceptions nommés
- 20. C++ problèmes iterator
- 21. Comment convertir un flottant en chaîne indépendamment des paramètres régionaux?
- 22. STL list_iterator question de code (STL 4.0.0)
- 23. C++ Container/Iterator Dépendance Problème
- 24. boost :: filter_iterator - comment le ferais-je avec le STL?
- 25. Qu'est-ce qu'un équivalent sécurisé d'effacement de STL non-nul?
- 26. stl :: find_if à la recherche d'utilisateur
- 27. documentation pour STL
- 28. Comment utiliser un STL différent avec g ++
- 29. Comment portable est un typedef STL?
- 30. Comment les conteneurs stl sont-ils supprimés?
+1 pour référence de typage statique du canard. :-) –
Vous voulez dire ++ - opérateur d'incrémentation? –
doh. En fait, je voulais écrire pré-incrément. Fixé. :) – jalf