2017-12-18 190 views
4

我发现它在某些时候进行以下检查一些模板代码:在模板方法消除警告由于unsignedness

template<class IntegralType> 
void randomFunction(IntegralType t) 
{ 
    ... 
    if (t < 0) 
    ... 
} 

代码的想法是,t是一个整体式的(无论是有符号或无符号)。代码工作得很好,无论签名如何,但编译器发出警告,因为在unsigned整数的情况下,检查将始终为真。

是否有方法C++ 03修改代码以摆脱警告而不是压制它?不知何故,我正在考虑检查T的签名,不知道它是可能的。

我知道C++ 11的is_signed,但我不确定它如何在C++ 03中实现。

+0

对于'unsigned IntegralType',您总是可以使用* specialization *,它不会进行比较并为其他常用代码调用一个或多个函数。 –

+0

@Someprogrammerdude看起来如何? 'template void randomFunction(unsigned IntegralType)''将'unsigned'解释为'unsigned int'并且抱怨。 – user2891462

+0

可能重复的[比较始终是错误的,因为范围有限...使用模板](https://stackoverflow.com/questions/2056996/comparison-is-always-false-due-to-limited-range-with-模板) – jww

回答

3

C++ 11 is_signedcppreference表明这是可能的实现:

namespace detail { 
template<typename T,bool = std::is_arithmetic<T>::value> 
struct is_signed : std::integral_constant<bool, T(-1) < T(0)> {}; 

template<typename T> 
struct is_signed<T,false> : std::false_type {}; 
} // namespace detail 

template<typename T> 
struct is_signed : detail::is_signed<T>::type {}; 

的问题是,is_integral_constant只在C++ 11也可以,但是,这可能起点为你在C++ 03中实现相同。

+0

无论如何,'integral_constant'几乎无法回到C++ 03,因为它是纯粹的库解决方案。来自早期C++ 11编译器的包含''integral_constant''的包含文件的代码以及所有基本类型特征应该在C++ 03中按原样编译。 –

+0

有没有人知道这是否适用于OSX,如版本10.8和10.9? Apple有时会提供一个不寻常的C++ std库。 – jww

6

具有触杀调度与性状:

template <typename T> 
bool is_negative(T t, std::true_type) 
{ 
    return t < 0; 
} 
template <typename T> 
bool is_negative(T t, std::false_type) 
{ 
    return false; 
} 

template<class IntegralType> 
void randomFunction(IntegralType t) 
{ 
    ... 
    if (is_negative(t, std::is_signed<IntegralType>::type()) 
    ... 
} 

std::is_signed可以在C++ 03中实现。

+0

应该不是IntegralType是T还是T是randomFunction中的IntegralType? –

+0

@RobertAndrzejuk:固定。 – Jarod42

1

我一直在寻找这个问题的解决方案一段时间。

我发现用的是同样的想法的最佳解决方案,在这个answer

if (!(t == 0 || t > 0)) 

,它可能是一个编译器特有的解决方法,但至少在G ++ 4.4.7警告消失。