Mam funkcje do konwersji różnych typów arytmetycznych na typ zmiennoprzecinkowy o połowie precyzji (tylko uint16_t
na najniższym poziomie) i mam różne funkcje dla typów źródeł całkowitych i zmiennoprzecinkowych, używając SFINAE i std::enable_if
:SFINAE rozróżnienie między znakiem i unsigned
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
}
nazywane są wewnętrznie z uniwersalnej matrycy przez konstruktora wyraźnej instancji:
template<typename T>
half::half(T rhs)
: data_(detail::conversion::to_half<T>(rhs))
{
}
To kompiluje i również działa dobrze. Teraz staram się odróżnić podpisanych i niepodpisanych liczb całkowitych, zastępując drugą funkcję z dwóch funkcji:
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
}
Ale gdy próbuję skompilować ten VS2010 daje mi
błędu 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)"
: funkcję szablon już zdefiniowany.
Wygląda na to, że nie można rozróżnić dwóch szablonów, ale oczywiście nie miał problemu z wersją integralną obok wersji zmiennoprzecinkowej.
Ale ponieważ nie jestem, że dużo szablon mag może być po prostu brakuje czegoś oczywiste tutaj (albo powinna ona faktycznie działa i jest po prostu bug VS2010). Dlaczego więc ta praca nie działa i jak można ją wykonać przy jak najmniejszej ilości nakładów na programowanie oraz w granicach funkcji standardowych (jeśli to możliwe)?
Nie jest jasne, czy 'is_signed' /' is_unsigned' wzajemnie się wyklucza (witaj 'char'?). Postaraj się, aby druga wersja wypowiedziała '! Std :: is_signed :: value'. –
Czy możesz spróbować użyć 'std :: is_signed :: value' dla jednego z członków i'! Std :: is_signed :: value' dla drugiego? Ma to na celu upewnienie się, że nie ma jakiegoś typu, który ma niespójne ustawienia dla 'is_signed' i' is_unsigned'. –
@KerrekSB & Dietmar Hah, to zrobili! Nie mogę uwierzyć, że to było takie łatwe. Jeśli ktoś doda to jako odpowiedź, zaakceptuję to. –