我有转换不同算术类型为半精度浮点类型(仅在最低级别上使用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::value && std::tr1::is_signed<_Ty>::value,T>::type)": 函数模板已经定义。 所以它似乎不能区分两个模板,但显然在浮点版本中与整数版本并存没有问题。 但由于我不是那么擅长模板这方面的魔法,我可能会错过一些明显的东西(或者它实际上应该工作,只是VS2010的错误)。那么为什么无法正常工作,如何在尽可能少的编程开销和纯标准功能的限制下使其正常工作(如果有可能)?
is_signed
/is_unsigned
是否互斥(你好,char
?)。尝试让第二个版本改为!std::is_signed<T>::value
。 - Kerrek SBstd::is_signed<T>::value
,在另一个成员中使用!std::is_signed<T>::value
吗?这只是为了确保没有某种类型的is_signed
和is_unsigned
设置不一致。 - Dietmar Kühlchar
既不是有符号整数类型也不是无符号整数类型。但是我记得is_signed
和is_unsigned
会处理这个问题:只有其中一个会报告char
为true
。 - Johannes Schaub - litbchar
是没问题的。不过,枚举和指针始终是错误的,我猜是因为它们不是算术类型。 - Kerrek SB