声明对于 gcc 是正确的
这里的这种说法似乎不正确:[…]
我不了解标准或 Visual Studio,但我知道我正在使用的 C++,它来自 GCC。在那里你可以看看相关的标题。
oistream::open
看起来像这样:
inline void
istream::open(const char* __s, ios_base::openmode __mode = ios_base::in) {
if (!_M_filebuf.open(__s, __mode | ios_base::in))
所以你在这里有两件事:一个默认函数参数,以防你在调用方法时没有指定一个,以及一个强制标志,它总是 or-ed 进入提供的模式。因此,无论您指定哪种模式,输入模式都将始终添加到您的规范中。其他代码,特别是构造函数,将委托给它。类似的情况也会发生ofstream::open
。另一方面,fstream::open
具有默认参数,但没有强制参数:
inline void
fstream::open(const char* __s,
ios_base::openmode __mode = ios_base::in | ios_base::out) {
if (!_M_filebuf.open(__s, __mode))
因此,不通过任何模式是可以的(至少在这个实现中,但请阅读@kmote 的答案以获取更多详细信息),但是如果您确实通过了任何模式,那么您必须同时通过其中一个in
或out
两个,因为您指定(或未能指定)的模式不会添加强制模式。
这是我阅读 Apache 文档的方式,源代码支持我的观点,至少对于我的实现而言。由于所有这些都在模板化代码中,因此您可以查看来自不同编译器的标头以了解它如何处理这些情况。所以看看 VS 头文件,看看basic_fstream
它的方法是如何实现的。
缺少编译器错误
否则,此代码将无法编译。
您的代码打开一个双向流仅用于输出,然后尝试从中输入内容。没有理由编译失败。流的静态类型是fstream
,即双向。只有在运行时,您才会将具有特定含义的特定标志传递给构造函数。编译器(通常)不会对此进行检查,因此当您的代码无法从流中实际读取时,您的代码将因此在运行时出现异常行为。
请注意,我不确定 Windows 是否真的支持打开文件仅用于输出。操作系统支持的唯一文件模式很可能是只读和读写。(请注意,我只是在这里推测。)在这种情况下,即使在运行时打开文件仅用于输出并随后从中读取也不会成为问题,因为out
仅使用或使用in|out
. 为了可移植性,应该选择正确的模式,因为那里有支持只写文件的内核。