0
votes

Décider de quelle structure de spécialisation de gabarit à utiliser à chaque fois

J'ai les déclarations suivantes dans c ++ : xxx

et j'ai les appels suivants ( a étend b < / code>): xxx

Je sais qu'il utilise la fonctionnalité de modèle mais je ne peux pas sembler comprendre comment il décide lequel choisir lequel choisir à chaque fois?

EDIT : Je sais ce que devrait être la sortie: xxx

Ma question est la suivante: comment le compilateur choisit le compilateur le bon? quel algorithme / méthode / méthode / approche dois-je penser dans ma tête afin de comprendre lequel on sera appelé


3 commentaires

Canasign peut être renommé is_same ...


@ Jarod42 Je sais ce qui devrait être la sortie. Je ne comprends pas pourquoi (comment le compilateur choisit le bon)


Votre problème est-il avec héritage? concept "plus spécialisé"?


4 Réponses :


0
votes

L'héritage possible ne compte pas ici.

Vous avez donc: xxx


0 commentaires

0
votes

Ma question est la suivante: comment le compilateur choisit le bon? quel algorithme / méthode / approche dois-je penser dans ma tête afin de comprendre lequel on sera appelé

L'algorithme est décrit dans le [Temp.class.spec.Match ] section (et les associés) de la norme particulière que vous ciblez.


0 commentaires

0
votes

Ma question est la suivante: comment le compilateur choisit le bon? quel algorithme / méthode / approche dois-je penser dans ma tête afin de comprendre lequel on sera appelé p>

Le compilateur Choisissez la version la plus spécialisée disponible (et donne une erreur s'il y a une ambiguïté en sélectionnant la plus spécialisation disponible). P>

Une version est plus spécialisée qu'un autre lorsque P>

1 ) Toutes les correspondances, des paramètres de modèle, pour plus spécialisées sont également des correspondances pour les moins spécialisés P>

2) et il y a des correspondances pour moins spécialisées qui ne correspondent pas aux correspondances pour plus spécialisée P> Dans votre cas, vous avez deux version de Canasign CODE>: la principale et la spécialisation. P>

La spécialisation est, évidemment, plus spécialisée que la version principale, donc au cas où de P>

template <typename, typename, typename>
struct foo 
 { };

template <typename A, typename B>
struct foo<A, A, B>
 { };

template <typename A>
struct foo<A, A, A>
 { };


3 commentaires

Il n'y a qu'une seule spécialisation en jeu ici, de sorte que ces règles ne s'appliquent pas.


@Acorn - Oui, dans la norme, la règle est écrite en appliquant le modèle principal uniquement lorsqu'aucune correspondance de spécialisation; D'autre part, vous ne pouvez pas écrire une spécialisation qui ne se spécialise pas (si vous essayez, compilez Modèle STRIT FOO {}; Modèle STRIT FOO {}; Vous obtenez une erreur car la spécialisation est spécialisée exactement comme modèle principal), donc je ne vois donc pas de différences pratiques.


OP demande comment le compilateur décide si la spécialisation ou le modèle principal doit être utilisé. La première étape consiste à décider quelles spécialisations correspondent (ou non). Ce que vous avez décrit est la commande entre spécialisations, qui se produit après la correspondance s'est produite s'il y en a plus d'un. Dans l'exemple de OP, il n'y en a qu'un, alors ce que vous décrivez ici n'influence pas la décision du compilateur.



0
votes

C'est une sorte de correspondance de modèle.

Ce sera une histoire juste. Il ne correspond pas exactement à la norme, mais je trouve qu'il génère une bonne intensité. xxx

C'est la spécificité principale. Il définit la signature de modèle - deux classes, telles que définies par . C'est aussi celui qui est instancié si rien d'autre correspond. xxx

Il s'agit d'une spécialisation secondaire. Ici, le sert un objectif différent; Il introduit des variables à la correspondance des motifs, pas des arguments.

Les arguments sont dans le partie. Le compilateur correspond à contre les arguments passés.

tout argument dans un "contexte déduit" est apparié de manière indépendante. Donc, si vous passez correspondant t1 = a puis t1 = b . Ceci est incompatible; La spécialisation ne correspond pas. Si vous passez correspondant t1 = A et t1 = A . Ceci est cohérent.

Les choses deviennent plus amicales lorsque vous faites . Ensuite, si vous passez , il essaierait t1 * = A et échouer; Mais si vous avez passé , il commencerait par t1 * = a * , puis bandez le * et obtenez et obtenez T1 = A , puis le refait à nouveau pour la 2e argument.

Les contextes non déduits sont différents. Lorsque vous avez un contexte non déduit, comme std :: activation_if_t , aucune correspondance de modèle n'est effectuée sur cet argument. Au lieu de cela, les autres arguments sont assortis de motif, puis les variables de modèle de spécialisation sont sous-associées. Si le type résultant correspond exactement à l'argument, il passe; Sinon, il échoue.

Le dernier bit commande. Si deux spécialisations secondaires passent, celle-ci est strictement "plus spécialisée" gagne. Si non plus strictement plus spécialisé, ni gagne. Les règles pour plus spécialisées sont complexes; L'idée intuitive est si une spécialisation pouvait toujours correspondre aux cas de l'autre, mais non inversement, celui qui correspond strictement moins est plus spécialisé.


0 commentaires