J'essaie d'avoir une spécialisation de modèle différente pour les classes qui ont une classe intérieure avec un nom particulier présent. J'ai pris une idée de ici A > et essayé ce qui suit: #include <iostream>
template< typename T, typename Check = void > struct HasXYZ
{ static const bool value = false; };
template< typename T > struct HasXYZ< T, typename T::XYZ >
{ static const bool value = true; };
struct Foo
{
class XYZ {};
};
struct FooWithTypedef
{
typedef void XYZ;
};
int main()
{
// The following line prints 1, as expected
std::cout << HasXYZ< FooWithTypedef >::value << std::endl;
// The following line prints 0. Why?
std::cout << HasXYZ< Foo >::value << std::endl;
return 0;
}
3 Réponses :
Voici une autre version qui détecte la présence de la classe interne:
Merci, mais je suis toujours très intéressé à savoir pourquoi ce que j'ai essayé n'a pas fonctionné.
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 code> partie de la question.
pour une explication sur la manière dont cela fonctionne, voir Cette question . p> p> A :: XYZ code> aurait besoin de
Void code> 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 code> typename:
Oh, donc il doit correspondre à void code> 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 code> et une spécialisation où la deuxième Arg correspond toujours à
annulation code>?
@dragonroot: Comme je l'ai dit, lisez la question liée. Si xyz code> existe à l'intérieur de
t code>, le
void _ <...> code> ne sera pas sfinae dehors et générera
annulation code >, qui rendra cette spécialisation partielle spécifique correspondant à toutes les instanciations où le deuxième paramètre est
vide code>, qui, grâce au défaut, doit toujours être le cas. Maintenant, si
xyz code> 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 code>? Si XYZ est typée à
int code>, 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 code> est fourni par la petite structure d'assistance. Pour votre code, oui, ça compte. Si
T :: XYZ code> existe et est
void code>, la spécialisation partielle lira
has_xyz
has_xyz
T :: xyz code> était
int code>, la spécialisation partielle lirait
has_xyz
annulation par défaut Code> 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 code>, c'est ce que
has_xyz
void code>.
Pourquoi ne pas simplement utiliser activé_if?
@Forever: Je suis intéressé par la théorie de l'opération derrière cette chose.