Search code examples
c++template-meta-programmingtemplate-specializationenable-ifclass-template

enable_if for class template specialization with argument other than void


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.


Solution

  • 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>.