Шаблоны функций не могут быть частично специализированными, и, как правило, не рекомендуется использовать специализацию шаблонов функций.
Один из способов добиться того, чего вы хотите, - использовать метод, называемый диспетчеризацией тегов, который в основном заключается в предоставлении функции пересылки, которая выбирает правильную перегрузку на основе значения дополнительного фиктивного аргумента:
#include <type_traits>
#include <cstdint>
template<class T>
int64_t to_int64t( const T& t, std::true_type )
{
return t;
}
template<class T>
int64_t to_int64t( const T& t, std::false_type )
{
return t.to_int64t();
}
template<class T>
int64_t to_int64t( const T& t )
{
return to_int64t(t, std::is_integral<T>());
}
int main()
{
int64_t i = 64;
auto x = to_int64t( i );
}
Другая возможность - использовать классическую технику SFINAE, основанную на std::enable_if
. Вот как это может выглядеть (обратите внимание, что, начиная с C ++ 11, аргументы шаблона по умолчанию в шаблонах функций разрешены):
#include <type_traits>
#include <cstdint>
template<class T, typename std::enable_if<
std::is_integral<T>::value>::type* = nullptr>
int64_t to_int64t( const T& t )
{
return t;
}
template<class T, typename std::enable_if<
!std::is_integral<T>::value>::type* = nullptr>
int64_t to_int64t( const T& t )
{
return t.to_int64t();
}
int main()
{
int64_t i = 64;
auto x = to_int64t( i );
}
Еще одна возможность, хотя и более подробная, состоит в том, чтобы определить шаблоны вспомогательных классов (которые могут быть частично специализированы) в пространстве имен detail
и предоставить глобальный сервер пересылки - я бы не использовал этот метод для этого варианта использования, но я показываю его, потому что он может пригодятся в связанных дизайнерских ситуациях:
#include <type_traits>
#include <cstdint>
namespace detail
{
template<class T, bool = std::is_integral<T>::value>
struct helper { };
template<class T>
struct helper<T, true>
{
static int64_t to_int64t( const T& t )
{
return t;
}
};
template<class T>
struct helper<T, false>
{
static int64_t to_int64t( const T& t )
{
return t.to_int64t();
}
};
}
template<class T>
int64_t to_int64t( const T& t )
{
return detail::helper<T>::to_int64t(t);
}
int main()
{
int64_t i = 64;
auto x = to_int64t( i );
}
person
Andy Prowl
schedule
24.03.2013