I know that a C++ compiler picks a template specialization in preference to the primary template:
template<class T, class Enable = void>
class A {}; // primary template
template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, void>> {
}; // specialization for floating point types
However, I don't understand why the selection fails when a type other than void
is used as argument to enable_if
:
template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, int>> {
}; // specialization for floating point types
The compiler would surely "see" class A<T, int>
.
So it certainly can't be SFINAE, nevertheless the primary template is preferred to the specialization.
This question arises from a context where a custom type detection machinery could be used instead of enable_if
, e.g. an SFINAE friendly type extractor like common_type
.
Specializations are irrelevant until the compiler knows which types it is going to use for the primary template.
When you write A<double>
, then the compiler looks only at the primary template and sees that you actually mean A<double,void>
.
And only then it is looking for specializations. Now, when your specialization is for A<double,int>
, then it is not suitable because you asked for A<double,void>
.