声明对于 gcc 是正确的
这里的陈述似乎不正确:[…]
我不了解标准或 Visual Studio,但我知道我正在使用的 C++,它来自 GCC。在那里你可以看看the relevant header。
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))
所以你在这里有两件事:一个 default 函数参数,以防你在调用方法时没有指定一个,以及一个 forced 标志,它总是或-编辑到提供的模式。因此,无论您指定哪种模式,输入模式都将始终添加到您的规范中。其他代码,特别是构造函数,将委托给它。 ofstream::open 也会出现类似的情况。另一方面,fstream::open 有 default 参数,但没有 forced 参数:
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。为了可移植性,应该选择正确的模式,因为那里有支持只写文件的内核。