Maison  >  Article  >  développement back-end  >  Pourquoi ma fonction générique pour les piles et les files d'attente d'impression échoue-t-elle et comment puis-je y remédier ?

Pourquoi ma fonction générique pour les piles et les files d'attente d'impression échoue-t-elle et comment puis-je y remédier ?

DDD
DDDoriginal
2024-11-01 22:17:02939parcourir

Why Does My Generic Function for Print Stacks and Queues Fail, and How Can I Fix It?

Pourquoi la fonction échoue et comment résoudre le problème

Le code fourni tente de créer une fonction générique capable d'imprimer à la fois les piles et les files d'attente . Cependant, cela échoue en raison d'un problème fondamental : les deux branches de l'instruction if-else doivent être compilables. Dans ce cas, ils ne le sont pas.

L'erreur se produit spécifiquement parce que la fonction membre top() n'est disponible que pour les piles, tandis que la fonction membre front() n'est disponible que pour les files d'attente. Le compilateur signale le problème lorsqu'il tente de compiler les deux branches pour le même type de conteneur, car il ne peut pas déterminer quelle fonction membre utiliser.

Une solution à ce problème consiste à utiliser une spécialisation partielle. La spécialisation partielle vous permet de définir différentes implémentations d'un modèle pour des types ou des classes spécifiques. Dans ce cas, vous pouvez définir des spécialisations partielles pour les piles et les files d'attente, en garantissant que chaque implémentation dispose de la fonction membre appropriée :

<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();
    }
}

Cette solution utilise une classe element_accessor pour accéder à la fonction membre appropriée pour chaque type de conteneur. En fournissant des spécialisations partielles pour les piles et les files d'attente, vous vous assurez que le code correct est compilé pour chaque cas.

Une autre solution, disponible en C 17 et versions ultérieures, consiste à utiliser if constexpr :

<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>

Cette solution utilise des expressions conditionnelles constexpr pour sélectionner le code correct en fonction du type de conteneur. En vérifiant le type de Cont au moment de la compilation, vous pouvez vous assurer que la fonction membre correcte est appelée pour chaque conteneur.

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