Одно слово: SFINAE.
Замена Ошибка не является ошибкой.
Ищите это слово с Google и откроете для вас новый мир.
Посмотрите на смысл своего кода.
std::is_integral<typename T>::value
Это логическое значение, в зависимости от типа T
со значением true
если T
является интегральным типом, false
иначе.
std::enable_if<bool B, typename T = void>::type
Это тип T
, когда B == true
, в противном случае ничего.
Таким образом, в вашем коде
template < class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
когда T
является интегральным типом, то второй (безымянный) аргумент шаблона замещается типа (по умолчанию: void
, но, в данном случае, точный тип не имеет значения), и функция активирована. Напротив, когда T
не является интегральным типом, происходит сбой при подстановке второго аргумента шаблона, и эта версия функции is_even()
не активирована (для типа T
), и это важный момент, это не является ошибкой (может быть активирована другая версия is_even()
).
Более интересным может быть представление, как реализовать альтернативную версию is_even()
, для нецелевых типов. Вы можете думать, что вы можете реализовать другую версию, свести на нет std::is_integral
template < class T,
class = typename std::enable_if<false == std::is_integral<T>::value>::type>
, но это не работает (ошибка и не компилировать), потому что у вас есть два is_even()
шаблонной функция, которая отличается (от шаблонов аргументов указуют) только для аргумента по умолчанию.
Решение может применить SFINAE к возвращаемому значению
#include <type_traits>
#include <iostream>
template <typename T>
typename std::enable_if<true == std::is_integral<T>::value, bool>::type
is_even (T const & i)
{ return ! (i%2); }
template <typename T>
typename std::enable_if<false == std::is_integral<T>::value, bool>::type
is_even (T const &)
{ return false; }
int main()
{
std::cout << "-- is 7 even ? " << is_even(7) << '\n';
std::cout << "-- is 8UL even ? " << is_even(8LL) << '\n';
std::cout << "-- is \"abc\" even ? " << is_even("abc") << '\n';
return 0;
}
Таким образом, у вас есть версия is_even()
включена для интегрального типа и второй версии (возвращающих даже false
) для не целочисленных типов.
p.s .: извините за мой плохой английский.
Это параметр шаблона по умолчанию без имени. Основной «другой вариант использования» - в шаблонах конструктора, поскольку конструкторы не имеют типа возврата. –