CTAD fail to deduce template argument with SFINAE in partial specialization

228 views Asked by At

I tried using CTAD with SFINAE in partial specializations, but it doesn't compile unless I add a seemingly useless deduction guide. What's the reason/limitation behind?

template<typename T, typename Enable = void>
struct A;

template<typename T>
struct A< T, std::enable_if_t<std::is_arithmetic_v<T>>>
{
    A(T) { std::cout << "Numerical"; }
};

template<typename T>
struct A<T, std::enable_if_t<!std::is_arithmetic_v<T>>>
{
    A(T) { std::cout << "Other"; }
};

template<typename T>
A(T)->A<T>; //Need to have this, otherwise doesn't compile

int main()
{
    A a{ 1 };
}
1

There are 1 answers

2
HolyBlackCat On BEST ANSWER

Implicitly generated deduction guides mirror the constructors of the primary template only, not of the specializations.

It will work if you get rid of one of the specializations, and move code from it into the primary template:

template<typename T, typename Enable = void>
struct A
{
    A(T) { std::cout << "Other\n"; }
};

template<typename T>
struct A< T, std::enable_if_t<std::is_arithmetic_v<T>>>
{
    A(T) { std::cout << "Numerical\n"; }
};