Понимание SFINAE
Насколько я знаю, SFINAE означает, что ошибки замещения не приводят к ошибкам компиляции, а просто удаляют прототип из списка возможных перегрузок.
Что я не понимаю: почему это СФИНА?
template <bool C, typename T = void> struct enable_if{};
template <typename T> struct enable_if<true, T> { typedef T type; };
Но это не так?
template <bool C> struct assert;
template <> struct assert<true>{};
Насколько я понимаю, основная логика здесь идентична. Этот вопрос возник из комментариев к этому ответу.
1 ответ
В C++98 SFINAE выполняется либо с типом возврата, либо с фиктивным аргументом функции с параметром по умолчанию
// SFINAE on return type for functions with fixed arguments (e.g. operator overloading)
template<class T>
typename std::enable_if< std::is_integral<T>::value, void>::type
my_function(T const&);
// SFINAE on dummy argument with default parameter for functions with no return type (e.g. constructors)
template<class T>
void my_function(T const&, std::enable_if< std::is_integral<T>::value, void>::type* = nullptr);
В обоих случаях замена T
чтобы получить вложенный тип type
это сущность SFINAE. В отличие от std::enable_if
, ваш assert
Шаблон не имеет вложенного типа, который можно использовать в части замещения SFINAE.
См. Превосходную презентацию Джонатана Уэйкли ACCU 2013 для получения более подробной информации, а также для выражения CINA 11 SFINAE. Среди прочего (как отметил @BartekBanachewicz в комментариях) теперь также возможно использование SFINAE в аргументах шаблона функции по умолчанию
// use C++11 default function arguments, no clutter in function's signature!
template<class T, class dummy = typename std::enable_if< std::is_integral<T>::value, void>::type>
void my_function(T const&);