Ce que je dis ci-dessous (sous OLD POST ) devrait être vrai dans une certaine mesure, mais le problème réel avec cela est que SFINAE est mal utilisé, donc je ne suis plus sûr que ce soit un bug dans gcc.
Une déclaration d'alias doit toujours réussir, vous ne pouvez pas y mettre SFINAE, car ce n'est pas une déclaration de classe ou de fonction ou des spécialisations (cela a du sens, car vous ne pouvez pas spécialiser les alias). Si la déclaration d'alias échoue, le programme est mal formé. Par conséquent, le compilateur peut supposer qu'il ne se produira jamais que la déclaration d'alias échoue tant que vous ne l'avez pas forcée à instancier un tel modèle.
Par conséquent, il est parfaitement acceptable pour le compilateur de penser que sfinae_v_t<T,...>
c'est toujours T
, puisque cela se produira, lorsque le programme n'est pas mal formé. Par conséquent, il verra que, dans tous les cas où le programme n'est pas mal formé, la spécialisation partielle ne se spécialise pas et, en tant que telle, elle vous dira qu'elle est mal formée. (C'est ce que fait Clang).
Je ne pense pas que le compilateur soit obligé de le faire. Et si ce n'est pas le cas, et pense simplement "Ok, sfinae_v_t
c'est un type quelconque", alors il n'est pas évident que ce soit une redéclaration. Je pense donc que jusqu'à ce que nous instancions l'un d'eux, il n'y a rien de mal à ne pas lancer d'erreur.
Mais lorsque nous l'instancions, il devrait y avoir le problème que nous avons une redéclaration ou que le programme est mal formé en raison de std::enable_if
l'argument du modèle. GCC devrait en prendre au moins un mais ne fait ni l'un ni l'autre.
Cela ne s'applique également absolument pas à l'exemple le plus facile sans std::enable_if
. Donc, je pense toujours que c'est un bug dans GCC, mais je suis suffisamment stupéfait pour ne plus pouvoir le dire avec certitude. Je dirais simplement que quelqu'un devrait signaler cela comme un bug et laisser les gens de gcc y réfléchir.
ANCIEN POST
Il s'agit d'un bogue dans gcc. La norme nous donne des règles pour convertir un modèle de classe en modèles de fonction. Un modèle de classe est plus spécialisé qu'un autre si sa fonction précède celle de l'autre dans l'ordre des modèles de fonction partielle.
J'ai créé les fonctions ici et maintenant gcc affirme que les appeler est ambigu, donc il faudrait aussi dire que les modèles de classe sont également spécifiés.
Remarque: En lisant attentivement la norme, le compilateur dans ma tête est d'accord avec clang.