2013-05-09 76 views
0

我們過度使用模板,並且我們不能始終告訴手頭類型的簽名,所以我們需要技巧來隱藏最終會優化的警告。我有一個簡單的ASSERT(condition)宏,如果條件不是真的,它會拋出一些東西。C++:從T到無符號T的轉換

目標是檢查T鍵入的值範圍count值。我們需要它至少爲零,最多不超過size_t

template<typename SomeIntegral> 
SomeIntegral ZERO() 
{ 
    return SomeIntegral(0); 
} 

template<typename T> 
class C 
{ 
public: 
    void f(T count) 
    { 
    std::vector<std::string> ret; 
    ASSERT(count>=ZERO<T>()); // Check #1 
    ASSERT(count<std::numeric_limits<size_t>::max()); // Check #2 
    ret.reserve(size_t(count)); // Needs check #1 and #2 to succeed. 
    // ... 
    } 
    // ... 
}; 

#1檢查編譯沒有警告,但#2檢查報告說comparison between signed and unsigned integer expressions,因爲在這種特殊情況下的計數有符號的類型。如果我能說ASSERT((unsigned T) count < std::numeric_limits<size_t>::max())或者類似的話......在這種情況下,轉換爲無符號T是安全的,因爲我們從檢查#1知道它至少爲零。

...或我可以使用什麼其他編譯器不可知的方法?

+0

爲什麼檢查agains'的std :: numeric_limits :: MAX()'和'不是的std :: numeric_limits :: MAX()'? – mfontanini 2013-05-09 12:20:40

+0

,因爲我將使用該值作爲需要'size_t'類型參數的'.reserve()'的參數。你說的那個檢查總是如此,除非他們是平等的。 – Notinlist 2013-05-09 12:22:55

回答

6

我認爲你可以使用std::make_signedstd::make_unsigned。無論哪個都適合需要。


這是一個自定義實現。

namespace internal { 

    #define MK_MAKESIGNED(T,V)    \ 
    template<> struct make_signed<T> {  \ 
     public:        \ 
     typedef V type;     \ 
    };          


    template<typename T> 
    struct make_signed { 
     typedef T type; 
    }; 

    MK_MAKESIGNED(unsigned int, signed int); 
    MK_MAKESIGNED(unsigned char, signed char); 
    // .... can convert anything to anything. 

    #undef MK_MAKESIGNED 

}; 


internal::make_signed<unsigned char>::type c; 
+0

我非常喜歡它,但它僅來自C++ 11。 http://en.cppreference.com/w/cpp/types/make_unsigned – Notinlist 2013-05-09 12:21:03

+2

總是有Boost的版本http://www.boost.org/doc/libs/1_53_0/libs/type_traits/doc/html/boost_typetraits/reference/ make_signed.html – 2013-05-09 12:23:01

+0

@Notinlist或者如果您只使用常見的整數類型,您可以編寫自己的。我將編輯答案。 – stardust 2013-05-09 12:24:23

1

應用static_cast<unsigned long>雙方的左手和右手邊的表達在你的第二個斷言:

ASSERT(static_cast<unsigned long>(count) 
     < static_cast<unsigned long>(std::numeric_limits<size_t>::max())); 

(我假定你的計數是整數,而不是浮 - 如果我錯了,走了最大的浮法型)。

+0

如果T大於'unsigned long',該怎麼辦? – Notinlist 2013-05-09 12:19:46

+0

去'長雙'。據我所知,這是最大的標準C++類型 - 請參閱http://www.cplusplus.com/doc/tutorial/variables/ – 2013-05-09 12:22:35