さまざまな算術型を半精度浮動小数点型 (uint16_t
最低レベルの a のみ) に変換する関数があり、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))
{
}
これはコンパイルされ、問題なく動作します。ここで、2 番目の関数を 2 つの関数に置き換えることで、符号付き整数と符号なし整数を区別しようとします。
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 )"
: 関数テンプレートは既に定義されています。
したがって、2 つのテンプレートを区別することはできないようですが、整数バージョンと浮動小数点バージョンでは明らかに問題はありませんでした。
しかし、私はそれほどテンプレートの魔術師ではないので、ここで明らかな何かが欠けている可能性があります (または、実際には機能するはずで、VS2010 のバグにすぎない可能性があります)。では、なぜこれが機能しないのでしょうか?また、プログラミングのオーバーヘッドをできるだけ少なくし、標準のみの機能の制限内で (可能であれば)、どのように機能させることができるのでしょうか?