一般如何将有符号和无符号整数相互转换而无需指定特定宽度?
例如:
uint8_t <-> int8_t
uint16_t <-> int16_t
uint32_t <-> int32_t
uint64_t <-> int64_t
Run Code Online (Sandbox Code Playgroud)
最好写成:
uint8_t <-> int8_t
uint16_t <-> int16_t
uint32_t <-> int32_t
uint64_t <-> int64_t
Run Code Online (Sandbox Code Playgroud)
但是,我怀疑这并不能达到我想要的效果。
我认为使用这种方法可以达到类似的效果,但我认为对于相同的数据宽度这样做可能会有一些语法糖。
但是,我怀疑这并不能达到我想要的效果。
事实上,您的怀疑是有效的:表达式 ,static_cast<signed>(x)完全等同于static_cast<signed int>(x),因此强制转换将始终int是给定平台上“默认”大小的对象(并且类似地,unsigned等同于unsigned int)。
但是,通过一些工作,您可以创建使用std::make_signed和std::make_unsigned类型特征结构的“通用”转换模板函数。
以下是此类函数的可能实现,其中包含一个简短的测试程序,该程序显示了不同输入类型宽度的一些推导结果类型:
#include <type_traits> // For make_signed and make_unsigned
template<typename T>
static inline auto unsigned_cast(T s)
{
return static_cast<std::make_unsigned<T>::type>(s);
}
template<typename T>
static inline auto signed_cast(T s)
{
return static_cast<std::make_signed<T>::type>(s);
}
#include <typeinfo> // For "typeid"
#include <iostream>
int main()
{
int16_t s16 = 42;
auto u16 = unsigned_cast(s16);
std::cout << "Type of unsigned cast is: " << typeid(u16).name() << "\n";
uint64_t u64 = 39uLL;
auto s64 = signed_cast(u64);
std::cout << "Type of signed cast is: " << typeid(s64).name() << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)