2015-07-11 14 views
2

所以我一直試圖讓在C「循環」按位移位++(11),我已經得到了基本的代碼到這一點:如何在模板函數C++改變類型名的簽署岬

#include <cstdio> 
#include <limits> // is_signed 
#include <limits.h> // CHAR_BIT 

template<typename T> 
T rotl(T input, unsigned int shift) 
{ 
    return (input<<shift)|(input>>(sizeof(T)*CHAR_BIT-shift)); 
} 

template<typename T> 
T rotr(T input, unsigned int shift) 
{ 
    return (input>>shift)|(input<<(sizeof(T)*CHAR_BIT-shift)); 
} 

int main() 
{ 
    int i = -5; 

    std::printf("%i\n", i); 

    i = rotl(i, 4); // or other value 
    std::printf("%i\n", i); 

    i = rotr(i, 4); // same value as above 
    std::printf("%i\n", i); 
} 

這給了我預期的行爲,當輸出如下所示:

-5 
-1 
-1 

因爲INT I簽訂,但如果我這樣做的代碼:

i = (int)rotl((unsigned int)i, 4); 
. . . 
i = (int)rotr((unsigned int)i, 4); 

輸出變爲:

-5 
-65 
-5 

它的工作原理與我想要的一樣。我還可以檢查使用numeric_limits T的簽約岬如下:

T rotr(T input, unsigned int shift) 
{ 
    if(std::numeric_limits<T>::is_signed == false){ 
     return() 
    }else{ 
     return // problem here 
    } 
} 

但我似乎無法弄清楚如何扭轉T的簽約岬,(unsigned T)是typenames無效。那麼我該如何去做這件事?我寧願不使用除標準庫(個人品味)以外的任何東西,但如果沒有可行的方法來做到這一點,我可能會考慮非標準選項。

回答

2

由於celticminstrel建議使用std::make_unsigned<T>::type

方法如下:


template&lttypename T> 
T rotl(T input, unsigned int shift) 
{ 
    typename std::make_unsigned&ltT>::type ii = static_cast&lttypename std::make_unsigned&ltT>::type>(input); 
    return static_cast&ltT>((ii<<shift)|(ii>>(sizeof(T)*CHAR_BIT-shift))); 
} 
+0

謝謝你,等待是因爲大量飲酒(酒還沒醒TBH),完美地工作我需要的東西。謝謝大家的貢獻。 – MetroidChild

+0

@MetroChild。別擔心。到過那裏。 :-) –