"less than" 与GCC 4与6的ifstream比较
"less than" Comparison on ifstream with GCC 4 vs. 6
我刚刚偶然发现了这段代码:
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
是一个关键字,不应该用作名称。
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么比较运算符如此快速
- ifstream什么都没读
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 比较字符数组
- 将模板化的类型与C++中的某些类/类型进行比较
- C++自定义比较函数
- 如何比较自定义类的std::变体
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- std::设置自定义比较器
- 布尔比较运算符是如何在C++中工作的
- C++将目录中的所有文件与::filesystem进行比较
- shell排序中的交换和比较
- 如何在C++中比较两个char数组
- catch框架有没有办法比较流或文件
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 智能指针作为无序映射键,并通过引用进行比较
- 比较if语句中的数组值和int值
- "less than" 与GCC 4与6的ifstream比较
- 为什么可以将 ifstream 对象与 0 进行比较