The rules for picking which class template specialization is preferred involve rewriting the specializations into function templates and determining which function template is more specialized via the ordering rules for function templates [temp.class.order]. Consider this example, then:
#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>{});
}
Both gcc and clang print 2
here. This makes sense with some previous examples - deducing against a non-deduced context (void
against void_t<T>
) is just ignored, so deducing <T, void_t<T>>
against <X*, void>
succeeds but deducing <T*, void>
against <Y, void_t<Y>>
fails in both arguments. Fine.
Now consider this generalization:
#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 << '
';
}
Both clang and gcc report this specialization as ambiguous, between 1
and 2
. But why? The synthesized function templates aren't ambiguous. What's the difference between these two cases?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…