Justement, je trouve plutôt utile que le compilateur refuse de compiler quand le cas n'est pas pertinent, ça évite les bogues…
Quand tu ajoutes une classe à ta hiérarchie, avec le visiteur polymorphe, tu dois déjà surcharger le accept. Bon, tu peux mettre un truc vide dans accept mais c'est un coup à l'oublier après (ça m'est déjà arrivé). Du coup, tu vas ajouter une méthode virtuelle au visiteur pour traiter cette nouvelle classe. Et il faudra ensuite ajouter toutes les surcharges dans tous les visiteurs. Enfin bref, tu te retrouves à devoir ajouter plein de code pour une simple petite classe.
Avec la version template, sans rien faire dans le accept et dans le visit, ça compile, et ça tombe dans le cas de base. Après, tu ajoutes le cas qui va bien dans le visit, et là, ça va même marcher pour quelques visiteurs pour lesquels tu auras regroupé les traitements pour une des classes mères. Donc dans ce cas, avec très peu de code, ça fonctionne plutôt pas mal.
Je ne vois vraiment pas l'intérêt?
Disons que tu veux afficher tes structures, là pas de souci, tu peux utiliser le visiteur qui renvoie void. Ensuite, tu veux calculer un truc sur tes structures, tu peux vouloir un visiteur qui renvoie directement le résultat du calcul plutôt que de passer par un membre. Exemple concret : tu veux calculer le type d'une expression binaire, tu vas définir un visiteur qui renvoie un truc de type Type que tu vas appliquer à des trucs de type Expression. Tu vas d'abord récupérer le Type de l'expression de gauche (à l'aide du même visiteur), puis le type de l'expression de droite puis, en fonction de l'opérateur, tu vas calculer le type de l'expression binaire et le renvoyer. Ne pas utiliser de type de retour va complexifier considérablement ton code.
Pas vraiment un plus, puisque tu le dis toi-même, ça s'applique aussi à la version polymorphe?
C'est un plus dans le sens où ça se fait rarement sur les versions polymorphes (je n'ai jamais vu aucun exemple qui le faisait) mais que ça pourrait se faire.
Si je résume, on aurai la version template qui permet d'éviter d'avoir à utiliser la RTTI et de casser l'ABI, et la version polymorphe qui elle offre de meilleures performances?
En gros. C'est plus subtil, il y a aussi des considérations de style, de flexibilité, etc.
[^] # Re: Avantage pas compris
Posté par rewind (Mastodon) . En réponse au journal Visiteurs en C++. Évalué à 3.
Quand tu ajoutes une classe à ta hiérarchie, avec le visiteur polymorphe, tu dois déjà surcharger le accept. Bon, tu peux mettre un truc vide dans accept mais c'est un coup à l'oublier après (ça m'est déjà arrivé). Du coup, tu vas ajouter une méthode virtuelle au visiteur pour traiter cette nouvelle classe. Et il faudra ensuite ajouter toutes les surcharges dans tous les visiteurs. Enfin bref, tu te retrouves à devoir ajouter plein de code pour une simple petite classe.
Avec la version template, sans rien faire dans le accept et dans le visit, ça compile, et ça tombe dans le cas de base. Après, tu ajoutes le cas qui va bien dans le visit, et là, ça va même marcher pour quelques visiteurs pour lesquels tu auras regroupé les traitements pour une des classes mères. Donc dans ce cas, avec très peu de code, ça fonctionne plutôt pas mal.
Disons que tu veux afficher tes structures, là pas de souci, tu peux utiliser le visiteur qui renvoie void. Ensuite, tu veux calculer un truc sur tes structures, tu peux vouloir un visiteur qui renvoie directement le résultat du calcul plutôt que de passer par un membre. Exemple concret : tu veux calculer le type d'une expression binaire, tu vas définir un visiteur qui renvoie un truc de type Type que tu vas appliquer à des trucs de type Expression. Tu vas d'abord récupérer le Type de l'expression de gauche (à l'aide du même visiteur), puis le type de l'expression de droite puis, en fonction de l'opérateur, tu vas calculer le type de l'expression binaire et le renvoyer. Ne pas utiliser de type de retour va complexifier considérablement ton code.
C'est un plus dans le sens où ça se fait rarement sur les versions polymorphes (je n'ai jamais vu aucun exemple qui le faisait) mais que ça pourrait se faire.
En gros. C'est plus subtil, il y a aussi des considérations de style, de flexibilité, etc.