Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
autres_collections [2016/01/23 20:35] gbdivers fail lors d'une modif |
autres_collections [2017/08/24 23:34] (Version actuelle) gbdivers |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ^ Chapitre précédent ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ Chapitre suivant ^ | + | ^ [[iterateurs|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[bitset|Chapitre suivant]] ^ |
__Manque move_iterator et make_move_iterator __ | __Manque move_iterator et make_move_iterator __ | ||
Ligne 10: | Ligne 10: | ||
{{ :liste.png |}} | {{ :liste.png |}} | ||
- | Les fonctionnalités disponibles ont forcement un impact sur ce que vous pouvez faire avec un itérateur. Pour gérer cela, les itérateurs sont organisés par catégories, chaque type d'itérateur reprenant les fonctionnalités de la catégorie précédente en ajoutant de nouvelles fonctionnalités. Par exemple, la catégorie ''InputIterator'' propose la fonctionnalité "élément suivant", la catégorie ''BidirectionalIterator'' propose les fonctionnalités de ''InputIterator'' et la fonctionnalité "élément précédent". | + | Les fonctionnalités disponibles ont forcément un impact sur ce que vous pouvez faire avec un itérateur. Pour gérer cela, les itérateurs sont organisés par catégories, chaque type d'itérateur reprenant les fonctionnalités de la catégorie précédente en ajoutant de nouvelles fonctionnalités. Par exemple, la catégorie ''InputIterator'' propose la fonctionnalité "élément suivant", la catégorie ''BidirectionalIterator'' propose les fonctionnalités de ''InputIterator'' et la fonctionnalité "élément précédent". |
Chaque collection propose donc un type d'itérateur. En connaissant ce type, vous pouvez connaître les fonctionnalités qui seront utilisables ou non. | Chaque collection propose donc un type d'itérateur. En connaissant ce type, vous pouvez connaître les fonctionnalités qui seront utilisables ou non. | ||
Ligne 174: | Ligne 174: | ||
La catégorie ''ForwardIterator'' ajoute la fonctionnalité "avancer de plusieurs éléments" aux catégories de base ''InputIterator'' et ''OutputIterator''. Il est bien sûr possible d'avancer de plusieurs éléments dans ces deux dernières catégories, mais il faut pour cela appliquer plusieurs fois une même opération "élément suivant". Avec ''ForwardIterator'', cela est réalisé en une seule opération. | La catégorie ''ForwardIterator'' ajoute la fonctionnalité "avancer de plusieurs éléments" aux catégories de base ''InputIterator'' et ''OutputIterator''. Il est bien sûr possible d'avancer de plusieurs éléments dans ces deux dernières catégories, mais il faut pour cela appliquer plusieurs fois une même opération "élément suivant". Avec ''ForwardIterator'', cela est réalisé en une seule opération. | ||
+ | |||
+ | Un exemples de collection proposant des itérateurs de type ''ForwardIterator'' est ''std::forward_list''. | ||
Encore une fois, il existe plusieurs syntaxes pour réaliser cette opération : avec les opérateurs ''+'' et ''+='' et avec la fonction ''std::advance''. Dans tous les cas, ces opérations prennent en paramètre un itérateur et une valeur entière correspondant au nombre d'éléments à avancer. | Encore une fois, il existe plusieurs syntaxes pour réaliser cette opération : avec les opérateurs ''+'' et ''+='' et avec la fonction ''std::advance''. Dans tous les cas, ces opérations prennent en paramètre un itérateur et une valeur entière correspondant au nombre d'éléments à avancer. | ||
Ligne 209: | Ligne 211: | ||
La catégorie '''' ajoute à la catégorie ''ForwardIterator'' le concept d'élément précédent. Sans surprise, il existe aussi plusieurs syntaxes, qui sont l'équivalent symétrique des syntaxes pour "élément suivant", avec les opérateurs ''--'' (pré et post-fixé) et la fonction ''std::prev'' (pour //previous//). | La catégorie '''' ajoute à la catégorie ''ForwardIterator'' le concept d'élément précédent. Sans surprise, il existe aussi plusieurs syntaxes, qui sont l'équivalent symétrique des syntaxes pour "élément suivant", avec les opérateurs ''--'' (pré et post-fixé) et la fonction ''std::prev'' (pour //previous//). | ||
+ | |||
+ | Un exemples de collection proposant des itérateurs de type ''BidirectionalIterator'' est ''std::list''. | ||
<code cpp main.cpp> | <code cpp main.cpp> | ||
Ligne 240: | Ligne 244: | ||
La dernière catégorie d'itérateur permet un accès "aléatoire" aux éléments d'une collection. Par "aléatoire", il ne fait pas comprendre "au hasard", mais "n'importe où". Par exemple, si une collection contient cinq éléments, il est possible d'accéder directement au quatrième élément, puis au deuxième, puis au cinquième, etc. | La dernière catégorie d'itérateur permet un accès "aléatoire" aux éléments d'une collection. Par "aléatoire", il ne fait pas comprendre "au hasard", mais "n'importe où". Par exemple, si une collection contient cinq éléments, il est possible d'accéder directement au quatrième élément, puis au deuxième, puis au cinquième, etc. | ||
+ | |||
+ | Des exemples de collection proposant des itérateurs de type ''RandomAccessIterator'' sont ''std::vector'' ou ''std::array''. | ||
L'accès à un élément quelconque est réaliser en utilisant l'opérateur ''[]'' post-fixé. Cet opérateur prend en argument l'indice de l'élément dans la collection. En C++, les indices commencent à zéro et finissent à ''size() - 1''. | L'accès à un élément quelconque est réaliser en utilisant l'opérateur ''[]'' post-fixé. Cet opérateur prend en argument l'indice de l'élément dans la collection. En C++, les indices commencent à zéro et finissent à ''size() - 1''. | ||
Ligne 307: | Ligne 313: | ||
<code cpp> | <code cpp> | ||
- | using forward_it = std::vector<int>; | + | using forward_it = std::vector<int>::iterator; |
using reverse_it = std::reverse_iterator<forward_it>; | using reverse_it = std::reverse_iterator<forward_it>; | ||
</code> | </code> | ||
Ligne 337: | Ligne 343: | ||
</code> | </code> | ||
- | Bien sûr, si vous récupérez un itérateur en utilisant ''begin'' ou ''end'', il est plus simple d'utiliser directement ''rbegin'' et ''rend''. Mais un itérator peut également être obtenu en utilisant un algorithme, comme par exemple ''std::find''. Vous pouvez souhaitez réaliser cette recherche dans le sens direct (donc à partir des itérateurs retournés par ''begin'' et ''end''). Puis appliquer un second algorithme dans le sens inverse en utilisant ''std::make_reverse_iterator''. | + | Bien sûr, si vous récupérez un itérateur en utilisant ''begin'' ou ''end'', il est plus simple d'utiliser directement ''rbegin'' et ''rend''. Mais un itérateur peut également être obtenu en utilisant un algorithme, comme par exemple ''std::find''. Vous pouvez souhaitez réaliser cette recherche dans le sens direct (donc à partir des itérateurs retournés par ''begin'' et ''end''). Puis appliquer un second algorithme dans le sens inverse en utilisant ''std::make_reverse_iterator''. |
==== Insertion et flux ==== | ==== Insertion et flux ==== | ||
Ligne 356: | Ligne 362: | ||
* ''front_inserter'' pour insérer au début d'une collection (le type correspondant est ''front_insert_iterator'') ; | * ''front_inserter'' pour insérer au début d'une collection (le type correspondant est ''front_insert_iterator'') ; | ||
- | * inserter'' pour insérer n'importe où dans une collection (le type correspondant est ''insert_iterator'') ; | + | * ''inserter'' pour insérer n'importe où dans une collection (le type correspondant est ''insert_iterator'') ; |
- | * front_inserter'' pour insérer à la fin d'une collection (le type correspondant est ''back_insert_iterator''). | + | * ''back_inserter'' pour insérer à la fin d'une collection (le type correspondant est ''back_insert_iterator''). |
Le code suivant montre l'utilisation de ces fonctions (avec une collection de type ''std::list'', qui permet d'utiliser les trois types d'insertion, alors que ''std::vector'' ne permet pas d’insérer au début de la collection) : | Le code suivant montre l'utilisation de ces fonctions (avec une collection de type ''std::list'', qui permet d'utiliser les trois types d'insertion, alors que ''std::vector'' ne permet pas d’insérer au début de la collection) : | ||
Ligne 370: | Ligne 376: | ||
std::list<char> out { '1', '2', '3', '4' }; | std::list<char> out { '1', '2', '3', '4' }; | ||
std::copy(begin(in), end(in), std::front_inserter(out)); | std::copy(begin(in), end(in), std::front_inserter(out)); | ||
- | for (auto c: out) std::cout << c; std::cout << std::endl; | + | for (auto c: out) std::cout << c; |
+ | std::cout << std::endl; | ||
out = { '1', '2', '3', '4' }; | out = { '1', '2', '3', '4' }; | ||
const auto it = std::find(begin(out), end(out), '3'); | const auto it = std::find(begin(out), end(out), '3'); | ||
std::copy(begin(in), end(in), std::inserter(out, it)); | std::copy(begin(in), end(in), std::inserter(out, it)); | ||
- | for (auto c: out) std::cout << c; std::cout << std::endl; | + | for (auto c: out) std::cout << c; |
+ | std::cout << std::endl; | ||
out = { '1', '2', '3', '4' }; | out = { '1', '2', '3', '4' }; | ||
std::copy(begin(in), end(in), std::back_inserter(out)); | std::copy(begin(in), end(in), std::back_inserter(out)); | ||
- | for (auto c: out) std::cout << c; std::cout << std::endl; | + | for (auto c: out) std::cout << c; |
+ | std::cout << std::endl; | ||
} | } | ||
</code> | </code> | ||
Ligne 418: | Ligne 427: | ||
int main() { | int main() { | ||
std::vector<int> v { 1, 2, 3, 4 }; | std::vector<int> v { 1, 2, 3, 4 }; | ||
- | std::copy(begin(v), end(v), | + | std::copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " - ")); |
- | std::ostream_iterator<int>(std::cout, " - ")); | + | |
} | } | ||
</code> | </code> | ||
Ligne 431: | Ligne 439: | ||
L'utilisation des autres adaptateurs d'itérateurs de flux est similaire. | L'utilisation des autres adaptateurs d'itérateurs de flux est similaire. | ||
- | ^ Chapitre précédent ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ Chapitre suivant ^ | + | ^ [[iterateurs|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[predicats|Chapitre suivant]] ^ |