Я запутался насчет второго параметра std :: enable_if.
Используя возвращаемый тип int, мы можем сделать это используя:
template <class T>
typename std::enable_if<mpi::is_builtin<T>::value, int>::type
foo() { return 1; }
Но как я могу использовать enable_if в параметре или шаблоне? В этом случае, в чем отличие функций тоже ниже:
template<class T ,
class = typename std::enable_if<std::is_integral<T>::value>::type >
T too(T t) { std::cout << "here" << std::endl; return t; }
int too(int t) { std::cout << "there" << std::endl; return t; }
Благодарю.
Это означает, что в случае
template<class T ,
class = typename std::enable_if<std::is_integral<T>::value>::type >
это становится
template<class T ,
class = void >
если условие std::is_integral<T>::value
является true
следовательно, функция разрешена для типа T
и, следовательно, участвует в разрешении перегрузки.
Если условие не выполняется, оно становится незаконным и typename std::enable_if<...>::type
делает недействительной функцию для типа T
, В вашем примере первый метод допускает все целочисленные типы (int
, unsigned
, long
, …) но нет классов и т. д.
Второй, int
— только версия в вашем примере потеряет некоторую информацию и преобразует значения из неподписанных в подписанные или сузит некоторые значения, поэтому в некоторых случаях первая версия может быть действительно полезной.
Обратите внимание, что void
на самом деле по умолчанию для второго параметра std::enable_if
, что часто достаточно для включения или отключения шаблонов и т. д., так как вам не нужен конкретный тип. Все, что вам нужно знать / обнаружить, является ли он действительным (void
) или недействительным, и в этом случае нет действительной замены для ::type
часть.
в чем отличие функций тоже ниже:
Одним из них является шаблон, который может быть вызван для любого типа CopyConstructible, enable_if
ограничивает его только при использовании аргумента шаблона по умолчанию:
#include <iostream>
template<class T ,
class = typename std::enable_if<std::is_integral<T>::value>::type >
T too(T t) { std::cout << "here" << std::endl; return t; }
int too(int t) { std::cout << "there" << std::endl; return t; }
int main()
{
too<double, void>(1.0);
}