现在我们有时必须使用二进制数据.在C++中,我们使用字节序列,因为开头char是我们的构建块.定义为sizeof1,它是字节.char默认情况下,所有库I/O函数都使用.一切都很好,但总是有一点担心,有点奇怪,一些人的错误 - 一个字节中的位数是实现定义的.
所以在C99中,决定引入几个typedef让开发人员轻松表达自己的固定宽度整数类型.当然可选,因为我们从不想伤害便携性.其中uint8_t,迁移到C++ 11中std::uint8_t,固定宽度的8位无符号整数类型,对于真正想要使用8位字节的人来说是完美的选择.
因此,开发人员接受了新工具并开始构建库,这些库明确表示它们接受8位字节序列std::uint8_t*,std::vector<std::uint8_t>或者其他方式.
但是,或许经过深思熟虑,标准化委员会决定不要求实施,std::char_traits<std::uint8_t>因此禁止开发人员轻松,便携地实例化,比如说,std::basic_fstream<std::uint8_t>并轻松读取std::uint8_t二进制数据.或许,我们中的一些人不关心字节中的位数并且对它感到满意.
但遗憾的是,两个世界相互冲突,有时您必须将数据作为char*并将其传递给期望的库std::uint8_t*.但是等等,你说,是不是char变量位并std::uint8_t固定为8?它会导致数据丢失吗?
嗯,这里有一个有趣的标准.的char定义为保持正好一个字节和字节是内存的最低可寻址的块,所以用比特宽度比的较小不能有一个类型char.接下来,它被定义为能够保存UTF-8代码单元.这给了我们最小--8位.所以现在我们有一个typedef,它要求是8位宽,并且是一个至少8位宽的类型.但有其他选择吗?是的,unsigned char.请记住,签名char是实现定义的.还有其他任何一种 谢天谢地,没有.所有其他整数类型都需要超出8位的范围.
最后,std::uint8_t是可选的,这意味着如果未定义使用此类型的库将无法编译.但如果它编译呢?我可以非常自信地说,这意味着我们在8位字节的平台上CHAR_BIT == 8.
一旦我们有这方面的知识,我们已经8位字节,这std::uint8_t是实现为char或者unsigned char,我们可以假设,我们可以做reinterpret_cast的char*到std::uint8_t*,反之亦然?它是便携式的吗?
这是我的Standardese阅读技巧让我失望的地方.我读了关于安全派生的指针([basic.stc.dynamic.safety]),据我所知,以下内容:
std::uint8_t* buffer = /* ... */ ;
char* buffer2 …Run Code Online (Sandbox Code Playgroud) 在这个答案和附带的评论中,Pavel Minaev提出以下论点:在C中,uint8_t可以使用typedef 的唯一类型是char和unsigned char.我正在看这个 C标准草案.
uint8_t意味着存在相应的类型int8_t(7.18.1p1).int8_t 是8位宽,没有填充位(7.18.1.1p1).uint8_t也是8位宽.unsigned char是CHAR_BIT位宽(5.2.4.2.1p2和6.2.6.1p3).CHAR_BIT 至少是8(5.2.4.2.1p1).CHAR_BIT最多为8,因为它们uint8_t是unsigned char,或者它unsigned char是非位域类型,其宽度是CHAR_BIT(6.2.6.1p4)的倍数.根据这个论点,我同意,如果uint8_t存在,那么它和它unsigned char具有相同的表示:8个值位和0个填充位.这似乎并不强迫它们成为同一类型(例如,6.2.5p14).
是否允许对uint8_t具有相同表示的扩展无符号整数类型(6.2.5p6)进行typedef unsigned char?当然它必须是typedef'd(7.18.1.1p2),并且它不能是除unsigned char(或者char它恰好是无符号)之外的任何标准无符号整数类型.这个假设的扩展类型不是字符类型(6.2.5p15),因此不符合对不兼容类型(6.5p7)的对象的别名访问,这让我觉得编译器编写者想要这样做的原因事情.
我有将不同的算术类型转换为半精度浮点类型的函数(只是uint16_t最低级别的函数),并且我使用SFINAE和整数和浮点源类型具有不同的函数std::enable_if:
template<typename T>
uint16_t to_half(typename std::enable_if<
std::is_floating_point<T>::value,T>::type value)
{
//float to half conversion
}
template<typename T>
uint16_t to_half(typename std::enable_if<
std::is_integral<T>::value,T>::type value)
{
//int to half conversion
}
Run Code Online (Sandbox Code Playgroud)
这些是通过显式实例化从通用模板化构造函数内部调用的:
template<typename T>
half::half(T rhs)
: data_(detail::conversion::to_half<T>(rhs))
{
}
Run Code Online (Sandbox Code Playgroud)
编译并运行也很好.现在我尝试通过用两个函数替换第二个函数来区分有符号和无符号整数:
template<typename T>
uint16_t to_half(typename std::enable_if<std::is_integral<T>::value &&
std::is_signed<T>::value,T>::type value)
{
//signed to half conversion
}
template<typename T>
uint16_t to_half(typename std::enable_if<std::is_integral<T>::value &&
std::is_unsigned<T>::value,T>::type value)
{
//unsigned to half conversion
}
Run Code Online (Sandbox Code Playgroud)
但是一旦我尝试编译这个VS2010给了我
错误C2995 ::
"uint16_t math::detail::conversion::to_half( std::enable_if<std::tr1::is_integral<_Ty>::value && std::tr1::is_signed<_Ty>::value, T>::type )"已定义的函数模板. …
这是我的程序中的一段代码。我正在使用int8_t数据类型,并且在输入/输出方面遇到一些问题。显然,int8_t在程序中使用需要-std=c++11为编译器设置标志g++。我这样做了,但出现运行时错误。这是我的代码:
#include <iostream>
#include <cstdint>
using std::cout;
using std::cin;
using std::endl;
int main() {
int8_t number;
cout << "Enter a number [1-100]: ";
cin >> number;
cout << "You entered: " << number << endl;
cout << number << " / 10 = " << (number / 10) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是程序的输出:
$ ./a.out
Enter a number [1-100]: 95
You entered: 9
9 / 10 = 5
Run Code Online (Sandbox Code Playgroud)
这$是 …
一小段代码让我发疯,但希望你可以阻止我跳出窗外.看这里:
#include <iostream>
#include <cstdint>
int main()
{
int8_t i = 65;
int8_t j;
std::cout << "i = " << i << std::endl; // the 'A' is ok, same as uchar
std::cout << "Now type in a value for j (use 65 again): " << std::endl;
std::cin >> j;
std::cout << "j = " << j << std::endl;
if (i != j)
std::cout << "What is going on here?????" << std::endl;
else
std::cout << "Everything ok." << std::endl;
return 0; …Run Code Online (Sandbox Code Playgroud)