我只是偶然发现了这段代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
这可以用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) {
~~~~~~~~~~~^~~
Run Code Online (Sandbox Code Playgroud)
我试图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;
}
Run Code Online (Sandbox Code Playgroud)
编译并运行良好,但我没有找到这个变化的好解释,可能是由于没有提出一个好的搜索词组合.
所以我的问题不是 "如何检查ofstream的有效性".已经有一些或多或少令人满意的答案("或多或少"因为问题似乎有点复杂).
在这里或这里或这里.
我的问题是解释GCC 4和GCC 6之间关于编译(export < 0)上述代码中的内容所做的更改.
谢谢你的任何指示.
Bau*_*gen 12
在预C++ 11之前,标准流可以隐式转换为void*,NULL指示坏流和非NULL流.
所以你得到的是(void*)export和之间的指针比较(void*)0,这是合法的(在"应该编译"的意义上)和非感性的.
在C++ 11中,流转换void*为由显式转换替换bool,它仍然允许像以前一样检查流的状态,但是使诸如你的无意义代码成为非法的.
这里重要的是从隐式转换到显式转换btw.如果新的转换bool是隐式的,代码仍然会编译并进行(bool) export < 0比较.但是通过显式转换,这需要强制转换.
关于gcc4和gcc6之间的区别:libstdc ++ 4.x中的流在这方面不符合C++ 11.在版本5中修复/实现了C++ 11流转换,以及包括流和SSO的移动语义在内的相当多的C++ 11缺点.
gcc4只是不完整的C++ 11功能,在这种情况下,它遵循旧规则,它不应该.
为了完整起见:正如评论中已经提到的那样,export是一个关键字,不应该用作名称.
| 归档时间: |
|
| 查看次数: |
255 次 |
| 最近记录: |