Pour comprendre pourquoi la fonction print_container échoue, nous devons analyser les propriétés du modèle std::is_same. Cette fonction compare deux types et renvoie vrai s'ils sont identiques. Dans ce cas, nous utilisons std::is_same pour déterminer si le type de conteneur Cont est identique à une pile ou à une file d'attente. Cependant, les branches de l'instruction if-else dépendent du type exact du conteneur, ce qui entraîne des erreurs de compilation puisque les deux branches doivent être compilables.
Solution 1 : Spécialisation partielle
Une solution consiste à utiliser une spécialisation partielle pour créer des implémentations distinctes de element_accessor pour les types de pile et de file d'attente. Cela nous permet de gérer l'extraction d'éléments en fonction du type de conteneur spécifique. Voici un exemple d'implémentation :
<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); std::cout << elem << '\n'; cont.pop(); } }
Dans cette solution, element_accessor fournit un moyen cohérent d'accéder à l'élément supérieur pour les piles et à l'élément frontal pour les files d'attente, résolvant ainsi le problème d'incompatibilité de type.
Solution 2 : if constexpr (C 17)
Si vous utilisez C 17 ou une version ultérieure, vous pouvez exploiter la syntaxe if constexpr pour implémenter un branchement basé sur les paramètres de type de modèle. Voici une version modifiée de la fonction print_container :
<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>
Dans cette version, les branches if constexpr sont évaluées au moment de la compilation en fonction des paramètres de type de modèle. Cela élimine le besoin d'une spécialisation partielle et garantit la sécurité du type.
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!