У меня есть базовая c gr asp SFINAE, и я думаю, что понимаю многие примеры того, как std::enable_if
использует его для выбора специализаций шаблонов функций, но мне трудно обернуть голову о том, как это работает для шаблонов классов.
Следующий пример взят из cppreference.com объяснения std::enable_if
:
template<class T, class Enable = void>
class A {}; // primary template
template<class T>
class A<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
}; // specialization for floating point types
Мне сложно понять, как использование std::enable_if
таким образом помогает выбрать специализацию. (Я не сомневаюсь, что это так.)
Когда компилятор видит объявление типа A<float> specialized;
, он увидит два возможных экземпляра шаблона, которые подходят:
- "primary template "
A<T, Enable>
, где T
- это тип float
, а Enable - это тип void
(из-за значения по умолчанию). - Специализация
A<T, void>
, где T
- тип float
и void
- результат выражения с enable_if
.
Разве это не двусмысленно? Оба результата фактически приводят к A<T, void>
, так почему выбрана специализация?
В другом случае, например A<int> primary;
, параметры компилятора выглядят так:
- первичный,
A<T, Enable>
, где T
- это тип int
, а Enable
- это тип void
. - Специализация,
A<T, ?>
, где T
- это тип int
а ?
означает, что я полностью потерялся. В этом случае условие enable_if
ложно, поэтому оно не определяет type
, что оставляет вам A<int, typename >
. Разве это не синтаксическая ошибка? Даже в лице СФИНАЭ?