Что такое возможная реализация?
Вы пробовали с
template <class T>
class C {
public: // VVVVVVVVVVVVVV .................................V U here, not T
template <typename U = T, std::enable_if_t<std::is_same_v<U, int>, int> = 0>
C() {}
template <typename U = T, std::enable_if_t<!std::is_same_v<U, int>, int> = 0>
explicit C() {}
};
?
- Почему этоне компилируется?
Проблема в том, что SFINAE, над методами класса, работает с параметрами шаблона самих методов.
То есть в исходном рабочем коде:
template <typename T,
typename std::enable_if<std::is_integral<T>::value, bool>::type = false >
S(T) {}
где T
- это параметр шаблона, специфичный для конструктора (выводится из единственного аргумента).
Напротив, в вашем ошибочном коде
template <std::enable_if_t<std::is_same_v<T, int>, int> = 0>
C() {}
конструкторы оценивают параметр шаблона класса (T
), а не методов.
Используя трюк typename U = T
, вы преобразуете T
, параметр шаблона класса, вU
, параметр шаблона методов (в вашем случае конструкторы, но работает и с другими методами), поэтому std::enable_if_t
с тестом, зависящим от U
, может включать / отключать конструкторы.