std::is_same pour l'impression de conteneurs génériques : pourquoi cela échoue et solutions
Vous avez rencontré un problème lors de la tentative d'écriture d'une fonction générique pour imprimer à la fois les conteneurs de pile et de file d'attente. La fonction comprenait initialement une instruction conditionnelle pour déterminer le type de conteneur (pile ou file d'attente) et accéder à ses éléments en conséquence. Cependant, cette approche entraînait des erreurs de compilation en raison de la différence de fonctions membres entre les deux types de conteneurs.
Comprendre le problème :
L'erreur de compilation provient du fait qu'une branche de l'instruction if-else tente d'accéder à front() sur un type de pile et à top() sur un type de file d'attente. Ces accesseurs ne sont pas disponibles sur les types respectifs, ce qui provoque une plainte du compilateur. C a un typage fort, exigeant qu'un type spécifique soit fourni avec les fonctions membres correspondantes qu'il prend en charge.
Résoudre le problème :
Pour résoudre ce problème, nous avons besoin une solution qui peut différencier les types de conteneurs tout en donnant accès à leurs fonctions membres spécifiques. Voici deux solutions possibles :
1. Spécialisation partielle avec accesseur :
Une approche consiste à utiliser la spécialisation partielle de modèle et à définir une fonction d'accesseur pour chaque type de conteneur. Cette fonction d'accesseur récupérera l'élément supérieur ou avant selon les besoins.
<code class="cpp">template <typename Cont> struct element_accessor; template <typename T> struct element_accessor<std::stack<T>> { const T& operator()(const std::stack<T>& s) const { return s.top(); } }; template <typename T> struct element_accessor<std::queue<T>> { const T& operator()(const std::queue<T>& q) const { return q.front(); } }; template<typename Cont> void print_container(Cont& cont){ while(!cont.empty()){ auto elem = element_accessor<Cont>{}(cont); // call the accessor function std::cout << elem << '\n'; cont.pop(); } }
2. if constexpr avec C 17 :
Si votre environnement de développement prend en charge C 17, vous pouvez utiliser l'instruction if constexpr, qui effectue une évaluation au moment de la compilation et permet une exécution conditionnelle en fonction du type de conteneur.
<code class="cpp">template<template<class> typename Cont, typename T> void print_container(Cont<T>& cont){ while(!cont.empty()){ if constexpr (std::is_same_v<Cont<T>, std::stack<T>>) std::cout << cont.top() << '\n'; else if constexpr (std::is_same_v<Cont<T>, std::queue<T>>) std::cout << cont.front() << '\n'; cont.pop(); } }</code>
Les deux solutions vous permettent d'écrire une fonction générique capable d'imprimer à la fois des conteneurs de pile et de file d'attente, partageant efficacement le code entre des algorithmes de recherche tels que DFS et BFS.
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!