std:: input_iterator_tag, std:: output_iterator_tag, std:: forward_iterator_tag, std:: bidirectional_iterator_tag, std:: random_access_iterator_tag, std:: contiguous_iterator_tag
|
Défini dans l'en-tête
<iterator>
|
||
|
struct
input_iterator_tag
{
}
;
|
(1) | |
|
struct
output_iterator_tag
{
}
;
|
(2) | |
|
struct
forward_iterator_tag
:
public
input_iterator_tag
{
}
;
|
(3) | |
|
struct
bidirectional_iterator_tag
:
public
forward_iterator_tag
{
}
;
|
(4) | |
|
struct
random_access_iterator_tag
:
public
bidirectional_iterator_tag
{
}
;
|
(5) | |
|
struct
contiguous_iterator_tag
:
public
random_access_iterator_tag
{
}
;
|
(6) | (depuis C++20) |
Définit la catégorie d'un itérateur. Chaque étiquette est un type vide.
Table des matières |
Catégorie d'itérateur
Pour chaque
LegacyIterator
de type
It
, un
typedef
std::
iterator_traits
<
It
>
::
iterator_category
doit être défini comme un alias vers l'une de ces étiquettes de type, pour indiquer la catégorie la plus spécifique à laquelle
It
appartient.
-
input_iterator_tagcorrespond à LegacyInputIterator . -
output_iterator_tagcorrespond à LegacyOutputIterator . -
forward_iterator_tagcorrespond à LegacyForwardIterator . -
bidirectional_iterator_tagcorrespond à LegacyBidirectionalIterator . -
random_access_iterator_tagcorrespond à LegacyRandomAccessIterator .
Les étiquettes de catégorie d'itérateur véhiculent des informations qui peuvent être utilisées pour sélectionner les algorithmes les plus efficaces pour l'ensemble d'exigences spécifiques impliqué par la catégorie.
Concept d'itérateur
Pour chaque type
Si
Dans tous les cas, chaque concept n'est pas satisfait si les opérations requises ne sont pas prises en charge, indépendamment de l'étiquette. |
(depuis C++20) |
Notes
Il n'existe pas de balise distincte pour
LegacyContiguousIterator
. Autrement dit, il n'est pas possible d'identifier un
LegacyContiguousIterator
en se basant sur son
iterator_category
.
Pour définir un algorithme spécialisé pour les itérateurs contigus, utilisez le concept
contiguous_iterator
.
(depuis C++20)
Il n'existe aucune correspondance entre
output_iterator_tag
et le concept
output_iterator
. Définir
iterator_concept
à
output_iterator_tag
indique uniquement que le type ne modélise pas
input_iterator
.
Exemple
Une technique courante pour la sélection d'algorithmes basée sur les étiquettes de catégorie d'itérateurs consiste à utiliser une fonction de dispatch (l'alternative est std::enable_if ). Les classes d'étiquettes d'itérateurs sont également utilisées dans les définitions de concepts correspondantes pour exprimer les exigences, qui ne peuvent pas être exprimées uniquement en termes de modèles d'utilisation. (depuis C++20)
#include <iostream> #include <iterator> #include <list> #include <vector> // Using concepts (tag checking is part of the concepts themselves) template<std::bidirectional_iterator BDIter> void alg(BDIter, BDIter) { std::cout << "1. alg() \t called for bidirectional iterator\n"; } template<std::random_access_iterator RAIter> void alg(RAIter, RAIter) { std::cout << "2. alg() \t called for random-access iterator\n"; } // Legacy, using tag dispatch namespace legacy { // Quite often implementation details are hidden in a dedicated namespace namespace implementation_details { template<class BDIter> void alg(BDIter, BDIter, std::bidirectional_iterator_tag) { std::cout << "3. legacy::alg() called for bidirectional iterator\n"; } template<class RAIter> void alg(RAIter, RAIter, std::random_access_iterator_tag) { std::cout << "4. legacy::alg() called for random-access iterator\n"; } } // namespace implementation_details template<class Iter> void alg(Iter first, Iter last) { implementation_details::alg(first, last, typename std::iterator_traits<Iter>::iterator_category()); } } // namespace legacy int main() { std::list<int> l; alg(l.begin(), l.end()); // 1. legacy::alg(l.begin(), l.end()); // 3. std::vector<int> v; alg(v.begin(), v.end()); // 2. legacy::alg(v.begin(), v.end()); // 4. // std::istreambuf_iterator<char> i1(std::cin), i2; // alg(i1, i2); // compile error: no matching function for call // legacy::alg(i1, i2); // compile error: no matching function for call }
Sortie :
1. alg() called for bidirectional iterator 3. legacy::alg() called for bidirectional iterator 2. alg() called for random-access iterator 4. legacy::alg() called for random-access iterator
Voir aussi
|
(obsolète en C++17)
|
classe de base pour faciliter la définition des types requis pour les itérateurs simples
(modèle de classe) |
|
fournit une interface uniforme pour les propriétés d'un itérateur
(modèle de classe) |