如何在模板函数 C++ 中更改类型名的签名
How to change a typename's signed-ness in template function c++
所以我一直在尝试在 C++ (11) 中进行 "looping" 位移,我得到了基本代码:
#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)
对类型名无效。那么我该怎么做呢?除了标准库(个人品味真的),我宁愿不使用任何东西,但如果没有合理的方法,我可能会考虑非标准选项。
正如 celticminstrel 建议使用 std::make_unsigned<T>::type
方法如下:
template<typename T>
T rotl(T input, unsigned int shift)
{
typename std::make_unsigned<T>::type ii = static_cast<typename std::make_unsigned<T>::type>(input);
return static_cast<T>((ii<<shift)|(ii>>(sizeof(T)*CHAR_BIT-shift)));
}
所以我一直在尝试在 C++ (11) 中进行 "looping" 位移,我得到了基本代码:
#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)
对类型名无效。那么我该怎么做呢?除了标准库(个人品味真的),我宁愿不使用任何东西,但如果没有合理的方法,我可能会考虑非标准选项。
正如 celticminstrel 建议使用 std::make_unsigned<T>::type
方法如下:
template<typename T>
T rotl(T input, unsigned int shift)
{
typename std::make_unsigned<T>::type ii = static_cast<typename std::make_unsigned<T>::type>(input);
return static_cast<T>((ii<<shift)|(ii>>(sizeof(T)*CHAR_BIT-shift)));
}