2017-12-18 191 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警告消失。