Maison >développement back-end >C++ >Comment puis-je rendre mes types personnalisés itérables à l'aide de boucles For basées sur une plage en C ?

Comment puis-je rendre mes types personnalisés itérables à l'aide de boucles For basées sur une plage en C ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-28 22:06:15564parcourir

How Can I Make My Custom Types Iterable Using Range-Based For Loops in C  ?

Utilisation de « boucles basées sur une plage » avec des types personnalisés

Intégration de types personnalisés

Pour activer les « boucles for basées sur une plage » sur votre type personnalisé, vous pouvez implémenter le suivants :

  • Fonctions membres : Définissez les fonctions membres begin() et end() qui renvoient des objets qui agissent comme des itérateurs.
  • Fonctions gratuites : Créez des fonctions gratuites begin(Type&) et end(Type&) avec le même espace de noms que votre type personnalisé, renvoyant des objets qui se comportent comme des itérateurs.

Espace de noms Considérations

  • Si votre type personnalisé appartient au xml espace de noms, définissez xml::begin() ou xml::end() pour garantir la bonne association d'espace de noms.

Exigences de valeur de retour

Les objets retournés par begin() et end() n'ont pas besoin d'être de véritables itérateurs. Ils doivent répondre aux exigences suivantes :

  • Implémenter pré- , garantissant des expressions d'initialisation valides.
  • Implémenter le binaire != pour la comparaison booléenne .
  • Implémentez unaire * pour fournir une valeur pour affectation à la variable de boucle.
  • Exposer un destructeur public.

Types découplés

En C 17, les types de begin et end ont été découplés. Cela permet à l’itérateur de fin d’avoir un type différent de celui de l’itérateur de début. Ceci est utile pour les itérateurs « sentinelles » qui ne prennent en charge que != avec le type d'itérateur de début, permettant une itération efficace sur les tampons de caractères terminés par un caractère nul.

Exemple d'extension de bibliothèque

Considérez un type de bibliothèque some_struct_you_do_not_control qui contient un vecteur d'entiers mais n'a pas les méthodes begin() et end().

namespace library_ns {
  struct some_struct_you_do_not_control {
    std::vector<int> data;
  };
}

Pour rendre ce type itérable, vous pouvez ajouter le fonctions suivantes à l'espace de noms library_ns :

namespace library_ns {
  int* begin(some_struct_you_do_not_control&amp; x){ return x.data.data(); }
  int* end(some_struct_you_do_not_control&amp; x){ return x.data.data()+x.data.size(); }
  int const* cbegin(some_struct_you_do_not_control const&amp; x){ return x.data.data(); }
  int* cend(some_struct_you_do_not_control const&amp; x){ return x.data.data()+x.data.size(); }
  int const* begin(some_struct_you_do_not_control const&amp; x){ return cbegin(x); }
  int const* end(some_struct_you_do_not_control const&amp; x){ return cend(x); }
}

Maintenant, vous pouvez parcourir le vecteur à l'aide de boucles for basées sur une plage :

library_ns::some_struct_you_do_not_control s;
for (int i : s) {
  // ...
}

Exemple de type personnalisé

Pour un type personnalisé que vous contrôlez, vous pouvez définir le begin () et end() directement dans le type :

struct egg_carton {
  std::vector<egg> eggs;
  auto begin() { return eggs.begin(); }
  auto end() { return eggs.end(); }
  // ...
};

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn