SFINAE有符号和无符号之间的区分 [英] SFINAE differentiation between signed and unsigned

查看:156
本文介绍了SFINAE有符号和无符号之间的区分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有用于将不同的算术类型转换为半精度浮点类型的函数(在最低级别上只是一个 uint16_t ),我有不同的整数和浮点函数源类型,使用SFINAE和 std :: enable_if

I have functions for converting different arithmetic types to a half precision floating point type (just a uint16_t on the lowest level) and I have different functions for integer and floating point source types, using SFINAE and 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
}

这些通过显式实例化从通用模板构造函数内部调用:

These are called internally from a universal templated constructor by explicit instantiation:

template<typename T>
half::half(T rhs)
    : data_(detail::conversion::to_half<T>(rhs))
{
}

这个编译也工作正常。现在我尝试区分有符号和无符号整数,通过用两个函数替换第二个函数:

This compiles and also works just fine. Now I try to differentiate between signed and unsigned integers, by replacing the second function with the two functions:

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给我的

But once I try to compile this VS2010 gives me


错误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)

error 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 )": function template already defined.

所以看起来它不能消除两个模板之间的歧义,但它显然没有问题,

So it seems it cannot disambiguate between the two templates, but it obviously had no problems with the integral version alongside the floating point version.

但是因为我不是一个模板魔术师,我可能只是缺少一些明显的在这里(或者也许应该实际工作和只是一个VS2010的错误)。那么,为什么不工作,如何使它尽可能少的编程开销和在标准功能的限制(如果可能的话)?

But since I'm not that much a a template magician I may just be missing something obvious here (or maybe it should actually work and is just a VS2010 bug). So why doesn't this work and how can it be made work with as few programming overhead as possible and in the limits of standard-only features (if even possible)?

推荐答案

如果这不工作,那么你的编译器是错误的。

If this doesn't work then your compiler is at error.


如果包含表达式的两个函数定义满足一个定义规则,则涉及模板参数的两个表达式被视为等效...

Two expressions involving template parameters are considered equivalent if two function definitions containing the expressions would satisfy the one definition rule ...

这是在这里考虑的最重要的规则(省略了...的细节)。您的两个模板不满足ODR,因为它们的令牌序列不同。

That's the most important rule to consider here (left out the details of "..."). Your two templates do not satisfy the ODR because their token sequences differ.


如果两个函数模板在同一作用域中声明,具有相同的名称,具有相同的模板参数列表,

Two function templates are equivalent if they are declared in the same scope, have the same name, have identical template parameter lists, and have return types and parameter lists that are equivalent using the rules described above to compare expressions involving template parameters.

因此,您的两个模板定义了不同的模板,并且不要冲突。您现在可以检查您的模板是否功能等同。如果对于任何可能的模板参数集合,您的 enable_if 表达式总是产生相同的值。但是因为 is_unsigned is_signed 不是这样,这也不是这样的。如果是这样,那么你的代码将是错误的,但不需要诊断(这实际上意味着未定义的行为)。

So your two templates define different templates and do not clash. You could now check whether your templates perhaps are "functionally equivalent". They would be if for any possible set of template arguments, your enable_if expression would always yield the same value. But since that is not true for is_unsigned and is_signed, this is not the case either. If it would, then your code would be ill-formed, but without requiring a diagnostic (which effectively means "undefined behavior").

这篇关于SFINAE有符号和无符号之间的区分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆