Les règles pour la cueillette de la classe template de la spécialisation est préférable d'impliquer la réécriture de l'spécialisations en fonction des modèles et de détermination du modèle de fonction est de plus en plus spécialisée par les règles d'ordonnancement pour les modèles de fonction [temp.classe.la commande]. Considérons cet exemple, puis:
#include <iostream>
template <class T> struct voider { using type = void; };
template <class T> using void_t = typename voider<T>::type;
template <class T, class U> struct A { };
template <class T> int foo(A<T, void_t<T>> ) { return 1; }
template <class T> int foo(A<T*, void> ) { return 2; }
int main() {
std::cout << foo(A<int*, void>{});
}
Gcc et clang imprimer 2
ici. Cela fait sens avec certains exemples précédents - en déduire à l'encontre d'un non déduit du contexte (void
contre void_t<T>
) est tout simplement ignorés, donc en déduire <T, void_t<T>>
contre <X*, void>
réussit, mais en déduire <T*, void>
contre <Y, void_t<Y>>
d'échec dans les deux arguments. Des beaux.
Considérons maintenant cette généralisation:
#include <iostream>
template <class T> struct voider { using type = void; };
template <class T> using void_t = typename voider<T>::type;
template <int I> struct int_ { static constexpr int value = I; };
template <class T, class U> struct A : int_<0> { };
template <class T> struct A<T, void_t<T>> : int_<1> { };
template <class T> struct A<T*, void> : int_<2> { };
int main() {
std::cout << A<int*, void>::value << '\n';
}
Les deux clang et gcc rapport de cette spécialisation comme ambiguë, entre 1
et 2
. Mais pourquoi? La synthèse des modèles de fonction ne sont pas ambigus. Quelle est la différence entre ces deux cas?