9
votes

Comment tester la présence d'une classe intérieure dans une classe via Sfinae?


2 commentaires

Pourquoi ne pas simplement utiliser activé_if?


@Forever: Je suis intéressé par la théorie de l'opération derrière cette chose.


3 Réponses :


2
votes

Voici une autre version qui détecte la présence de la classe interne: xxx


1 commentaires

Merci, mais je suis toujours très intéressé à savoir pourquoi ce que j'ai essayé n'a pas fonctionné.



4
votes

réponse à la question initiale forte>

la spécialisation de modèle que vous avez définie ici: p> xxx pré>

prendra effet lorsque quelqu'un utilise le type de données HASXYZ CODE> pour certains types de données A code>. p>

Notez que, quel que soit le a code> est, A :: XYZ CODE> est un type de données totalement indépendant de A code>. Les classes intérieures sont des types de données à part entière. Lorsque vous utilisez A code> comme premier argument de modèle, il n'ya absolument aucune raison pour que le compilateur suppose que vous souhaitez utiliser quelque chose appelé A: xyz code> comme deuxième argument, même Si une classe intérieure de ce nom existe, et même si cela dirigeait le compilateur à une spécialisation de gabarit qui correspond exactement aux arguments de modèle exactement. Les spécialisations de modèles sont trouvées sur la base des arguments de modèle fournis par le codeur, non basés sur des arguments de modèle éventuels em> autres. P>

quand vous utilisez hasxyz code >, il reste à l'aide de l'argument de modèle par défaut vide code> pour le deuxième paramètre. p>

Inutile de dire que si vous deviez utiliser HASXYZ code> explicitement, vous obtiendrez la sortie attendue. Mais ce n'est évidemment pas ce que vous avez voulu. P>

J'ai peur que le seul moyen d'obtenir ce dont vous avez besoin est std :: activer_if code> (ou quelque chose qui fonctionne de la même manière). p>


réponse à la question supplémentaire (après la mise à jour) forte> p>

Considérez la simplification ci-dessous: P>

  template<class T1 = int, class T2 = int> class A;


2 commentaires

Vos réponses semblent être la bonne réponse, mais il y a quelque chose qui me manque encore ici, je pense. J'ai édité la question pour être plus spécifique. Pourriez-vous modifier le vôtre pour clarifier pourquoi un type typéfed est dépendant, mais une classe intérieure n'est pas?


@dragonroot: J'ai ajouté une réponse au Typedef partie de la question.



1
votes

A :: XYZ aurait besoin de Void pour avoir la spécialisation partielle sélectionnée, qui ne peut jamais être le cas pour un type de classe. Une façon de le faire fonctionner consiste à utiliser un faux dépendant void typename: xxx

pour une explication sur la manière dont cela fonctionne, voir Cette question .


6 commentaires

Oh, donc il doit correspondre à void qui a été donné dans la déclaration de modèle initiale? Maintenant je suis perdu. Comment toute cette spécialisation fonctionne-t-elle dans ce cas, où j'ai deux arguments initialement, le second étant fait défaut à Void et une spécialisation où la deuxième Arg correspond toujours à annulation ?


@dragonroot: Comme je l'ai dit, lisez la question liée. Si xyz existe à l'intérieur de t , le void _ <...> ne sera pas sfinae dehors et générera annulation , qui rendra cette spécialisation partielle spécifique correspondant à toutes les instanciations où le deuxième paramètre est vide , qui, grâce au défaut, doit toujours être le cas. Maintenant, si xyz n'existe pas, l'ensemble de la spécification partielle ne correspond pas essentiellement et le modèle de base sera sélectionné.


Oui, mais ma question était ici, pourquoi devait-elle être void ? Si XYZ est typée à int , cela ne fonctionnerait pas. Pourquoi? J'ai mis à jour la question (à nouveau) pour demander cela aussi.


@dragonroot: Avec le code i Publié, peu importe, car le void est fourni par la petite structure d'assistance. Pour votre code, oui, ça compte. Si T :: XYZ existe et est void , la spécialisation partielle lira has_xyz . L'argument par défaut sera ensuite appliqué chaque fois que vous utilisez has_xyz qui entraînera la sélection de la spécialisation partielle. Si T :: xyz était int , la spécialisation partielle lirait has_xyz et le annulation par défaut L'argument ne correspondrait plus.


Pourquoi cette spécialisation partielle n'a-t-elle été sélectionnée que si la deuxième valeur d'argumentation correspond à la valeur par défaut du modèle initial? Je suppose que ma question est plus sur la façon dont l'ensemble de la sélection de spécialisation fonctionne. La lecture de la norme serait trop épaisse, et je ne sais pas vraiment où regarder d'autre.


@dragonroot: Vous dites au compilateur d'utiliser la spécification partielle si le deuxième paramètre est void , c'est ce que has_xyz signifie. Et par défaut, le deuxième argument est void .