"less than" 与GCC 4与6的ifstream比较

"less than" Comparison on ifstream with GCC 4 vs. 6

本文关键字:ifstream 比较 GCC less than      更新时间:2023-10-16

我刚刚偶然发现了这段代码:

std::string export_str = "/path/to/file";
std::ofstream export(export_str.c_str());
if (export < 0) {
std::cout << "Unable to export" << std::endl;
return -1;
}

这在GCC 4.9.3中编译和运行良好,但在GCC 6.1.1中出现此错误:

error: no match for ‘operator<’ (operand types are ‘std::ofstream {aka std::basic_ofstream<char>}’ and ‘int’)
if (export < 0) {
~~~~~~~~~~~^~~

我尝试了GCC 6与:
-std=c++98(编译)
-std=c++03(编译)
-std=c++11(编译而不是)

编辑:但是,在GCC 4中,它仍然使用-std=c++11进行编译。下面的回答也解释了这一具体事实

所以我想这方面的标准发生了变化。

经过一番研究,我将代码改为:

std::string export_str = "/path/to/file";
std::ofstream export(export_str.c_str());
if (export.fail()) { // <-- related change
std::cout << "Unable to export" << std::endl;
return -1;
}

这编译和运行都很好,但我没有找到对这一变化的好解释,可能是因为没有找到一个好的搜索词组合。

所以我的问题是而不是"如何检查流的有效性"。已经有一些或多或少令人满意的答案了("或多或少"是因为这个问题似乎有点复杂)
这里或这里或这里。

我的问题是解释GCC 4和GCC 6之间关于编译上述代码中的(export < 0)之类的内容所做的更改。

谢谢你的指点。

Pre-C++11,标准流可隐式转换为void*,其中NULL表示坏流,非NULL表示好流。

因此,您得到的是(void*)export(void*)0之间的指针比较,这既是合法的(在"应该编译">的意义上),也是无意义的。

在C++11中,到void*的流转换被到bool的显式转换所取代,这仍然允许像以前一样检查流的状态,但会使像您这样的无意义代码成为非法代码。

这里重要的是从隐式到显式转换的变化。顺便说一句,如果对bool的新转换是隐式的,代码仍然会编译并进行(bool) export < 0比较。但对于显式转换,则需要强制转换。


关于gcc4和gcc6之间的差异:libstdc++4.x中的流在这方面不符合C++11。C++11流转换,以及C++11的一些缺点,包括流和SSO的移动语义,在版本5中得到了修复/实现。

gcc4只是没有完成C++11的功能,在这种情况下,它遵循了不应该遵循的旧规则。


为了完整起见:正如评论中已经提到的,export是一个关键字,不应该用作名称。