У меня есть функции для преобразования различных арифметических типов в тип с плавающей запятой половинной точности (просто uint16_t
на самом низком уровне), и у меня есть различные функции для целочисленных типов и типов с плавающей запятой, используя SFINAE и std::enable_if
:
template<typename T>
uint16_t to_half(typename std::enable_if<
std::is_floating_point<T>::value,T>::type value)
{
//float to half conversion
}
template<typename T>
uint16_t to_half(typename std::enable_if<
std::is_integral<T>::value,T>::type value)
{
//int to half conversion
}
Они вызываются внутренне из универсального шаблонного конструктора путем явной реализации:
template<typename T>
half::half(T rhs)
: data_(detail::conversion::to_half<T>(rhs))
{
}
Это компилируется, а также работает просто отлично.Теперь я пытаюсь различить целые числа со знаком и без знака, заменяя вторую функцию двумя функциями:
template<typename T>
uint16_t to_half(typename std::enable_if<std::is_integral<T>::value &&
std::is_signed<T>::value,T>::type value)
{
//signed to half conversion
}
template<typename T>
uint16_t to_half(typename std::enable_if<std::is_integral<T>::value &&
std::is_unsigned<T>::value,T>::type value)
{
//unsigned to half conversion
}
Но как только я пытаюсь скомпилировать этот VS2010, я получаю ошибку
C2995: "uint16_t math::detail::conversion::to_half( std::enable_if<std::tr1::is_integral<_Ty>::value && std::tr1::is_signed<_Ty>::value, T>::type )"
: шаблон функции уже определен.
Так что, похоже, он не может устранить неоднозначность между двумя шаблонами, но у него, очевидно, не было проблем с интегральной версией наряду с версией с плавающей запятой.
Но так как я не так уж много интересуюсь шаблонным фокусником, я, возможно, просто упускаю что-то очевидное здесь (или, может быть, оно действительно должно работать и это просто ошибка VS2010).Так почему же это не работает и как можно заставить его работать с минимальными затратами на программирование, насколько это возможно, и в рамках только стандартных функций (если вообще возможно)?