2

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 };
}
sz ppeter
  • 1,698
  • 1
  • 9
  • 21

1 Answers1

3

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"; }
};
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • 2
    Just `delete`ing `A(T)` in the primary might be better, especially if the sfinae set is more complicated. Like [this](https://godbolt.org/z/7M55rE). – cigien Oct 03 '20 at 13:35
  • That sounds unreasonable. Since I can SFINAE an overload of "factory functions" that work as constructors. – sz ppeter Oct 03 '20 at 13:39