$ file testfile.txt
testfile.txt: ASCII text
$ cat testfile.txt
aaaabbbbccddef
#include <iostream>
#include <fstream>
#include <string>
#include <cstdint>
typedef uint8_t byte; // <-------- interesting
typedef std::basic_ifstream<byte> FileStreamT;
static const std::string FILENAME = "testfile.txt";
int main(){
FileStreamT file(FILENAME, std::ifstream::in | std::ios::binary);
if(!file.is_open())
std::cout << "COULD NOT OPEN FILE" << std::endl;
else{
FileStreamT::char_type buff;
file.read(&buff,1);
std::cout << (SOMECAST)buff; // <------- interesting
}
std::cout << "done" << std::endl;
}
取决于typedef中的内容以及它被转换为(或不转换)的内容,它会执行各种愚蠢的事情。
它恰好与'typedef char'一起使用而且没有强制转换。 (按照预期将97转换为int)
uint8_t和int8_t都将打印
没有演员阵容
在转换为char或unsigned char时没有任何内容
8当转换为int或unsigned时(虽然ASCII'a'应为97)
我设法打印了一个“ ”字符,但忘记了它是什么情况。
为什么我会得到这些奇怪的结果?
从给出的答案中得出结论:仅使用char实例化流(或标准中也提到的宽字符之一),否则您将得不到编译器警告和静默失败
标准保证这些事情是非常可悲的
答案 0 :(得分:2)
template std::basic_ifstream
的声明是:
template<
class CharT,
class Traits = std::char_traits<CharT>
> class basic_ifstream;
C ++ 03 Standard(21.1 / 1)要求库定义特化
std::char_traits<CharT>
= CharT
,char
的{{1}}。
C ++ 11标准(C ++ 11 21.2 / 1)要求库定义特化
wchar_t
= std::char_traits<CharT>
,CharT
,char
,char16_t
的{{1}}。
如果您使用char32_t
实例化wchar_t
而不是其中之一
由您编制的标准提名的2 [4]种类型
除非你自己,否则行为将是不确定的
根据需要定义std::basic_ifstream<Other>
然后实例化
Other
。
续以回应OP的评论。
请求my_char_traits<Other>
不会激发模板实例化
错误:模板定义为,以便您可以将其专门化,但是
std::basic_ifstream<Other,my_char_traits<Other>>
的默认(非特定)实例化很可能错误
或者确实对于任何给定的std::char_traits<Other>
,其中错误意味着不满足
标准对每个C ++的角色特征类的要求03§21.1.1/ C ++11§21.2.1。
您怀疑typedef可能会阻碍模板特化的选择
对于Other
- ed类型,即CharT
和typedef
这一事实
是基础字符类型的typedef可能导致uint8_t
与int8_t
不同,其中 FCT
是别名的基本字符类型。
忘记这种怀疑。std::basic_ifstream<byte>
是透明的。你似乎相信一个
typedef std::basic_ifstream<FCT>
和typedef
必须是int8_t
,在这种情况下 - 除非
typedef以某种方式与模板分辨率相关 -
您测试过的行为不当uint8_t
实例之一
必须是char
但是basic_ifstream
无害的事实呢?那种信念
std::basic_ifstream<char>
或typedef char byte
= int8_t
为假。你会发现uint8_t
是char
的别名,而int8_t
是signed char
的别名。
但uint8_t
和unsigned char
与signed char
的类型不同:
C ++ 03 /11§3.9.1/ 1
Plain char,signed char和unsigned char是三种不同的类型
因此unsigned char
和char
都是默认值,
模板char_traits<int8_t>
的非专业化实例化,你有
没有权利期望他们满足该标准的要求
角色特征。
您发现没有错误行为的一个测试用例是char_traits<uint8_t>
= char_traits
。
这是因为byte
是提供的标准专业化
由图书馆。
你观察到的所有不端行为与之间的联系
您已替换char
的类型:
char_traits<char>
没有。由于您的测试文件包含ASCII文本,SOMECAST
是标准所保证的std::cout << (SOMECAST)buff; // <------- interesting
唯一的实例化
阅读它。如果您在程序中使用basic_ifstream<char>
读取文件
那么你说你替换的演员都没有意外
结果:basic_ifstream
= typedef char byte
或SOMECAST
将输出char
,并且
unsigned char
= a
或SOMECAST
将输出int
。
所有不当行为都来自unsigned int
与97
的实例化
标准不保证的某种类型。