Специализации не являются перегрузками.Они соответствуют шаблону.
Нет способа "перегрузить" шаблон, как вы хотите, если не считать магических значений.
template< unsigned fractional >
class Q<0u, fractional>
это просто шаблон соответствует.
Ваши аргументы всегда
template< unsigned integral, unsigned fractional >
class Q
, и ваша специализация совпадает, когда кто-то передает 0u
для integral
.Таким образом, он соответствует
Q<0u, fractional>
, он не соответствует
Q<fractional>
Теперь, как уже упоминалось, вы можете сделать это с помощью магических значений:
template< unsigned integral, unsigned fractional=-1 >
class Q
template< unsigned fractional >
class Q<fractional, -1>:Q<0u, fractional> {}
, но это также происходит, если кто-то передает -1
вручную.
В c ++ 20 вы можете иметь пользовательские типы в качестве шаблонных параметров шаблонных типов,так что вы можете сделать что-то вроде:
template< unsigned A, optional<unsigned> B = {} >
class Q;
template< unsigned integral, unsigned fractional >
class Q< integral, optional<unsigned>(fractional) > // 2 arg case
template< unsigned fractional >
class Q< fractional, nullopt >:Q<0u, fractional> {}; // 1 arg case
, но это еще не здесь.