У меня есть функции для преобразования различных арифметических типов в тип с плавающей точкой с половинной точностью (всего лишь 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). Итак, почему эта работа не работает и как она может работать с как можно меньшим количеством служебных программ программирования и в рамках стандартных возможностей (если возможно)?