【发布时间】:2012-03-06 08:07:39
【问题描述】:
我有将不同的算术类型转换为半精度浮点类型的函数(只是最低级别的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 错误)。那么为什么这不起作用?如何在尽可能少的编程开销和仅限标准功能的限制(如果可能的话)内使其工作?
【问题讨论】:
-
不清楚
is_signed/is_unsigned是否互斥(你好char?)。尝试将第二个版本改为!std::is_signed<T>::value。 -
您可以尝试将
std::is_signed<T>::value用于其中一个成员,将!std::is_signed<T>::value用于另一个成员吗?这只是为了确保不只是某些类型的is_signed和is_unsigned设置不一致。 -
@KerrekSB & Dietmar 哈,做到了!不敢相信有那么容易。如果有人将其添加为答案,我会接受。
-
@Kerrek
char既不是有符号整数类型也不是无符号整数类型。但是 IIRCis_signed和is_unsigned会处理这一点:只有其中一个会为char报告true。 -
@JohannesSchaub-litb:你说得对,
char没问题。但是,枚举和指针总是错误的;我猜是因为它们不是算术类型。
标签: c++ templates c++11 sfinae