Понимание 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&);
Другие вопросы по тегам