Clang делает вывод неправильно. Это похоже на эту ошибку , связанную с этим вопросом (не совсем то же самое, что вы используете auto в параметрах шаблона, что помешает вам скомпилировать с использованием stdc ++ 14).
Интересный случай - это не тот случай, если это полная специализация; только по частичной специализации:
#include <iostream>
enum class E {};
inline static constexpr auto e = E{};
template <auto a, int b>
class FOO;
template <int a, int b > class FOO<a, b> {};
template <int b> class FOO<e, b> {};
template <auto a, int b>
class BAR;
template <int a, int b > class BAR<a, b> {};
template <> class BAR<e, 0> {};
template <auto a>
class BAZ;
template <int a> class BAZ<a> {};
template <> class BAZ<e> {};
int main() {
// FOO <0, 0> foo; // <= Not Ok
BAR<0, 0> bar; // <= Ok
BAZ<0> baz; // <= Ok
}
Любое решение, которое вынуждает удерживать параметр шаблона типа, будет работать, поэтому предложенное вами решение является абсолютно верным. ИМХО, я бы не использовал auto в параметре шаблона, когда нет необходимости улучшать читабельность:
template <typename T, T value, int> class S_impl; // <= this auto is not necessary
template <int a, int b> class S_impl<int, a, b> {};
template <int b> class S_impl<E, e, b> {};
// Either define S to use S<0,0> or directly use S_impl<int, 0, 0>
template <auto a, int b> using S = S_impl<decltype(a), a, b> // <= this auto is necessary