与GCC 4 vs. 6相比ifstream的“小于”

布芬格

我只是偶然发现了这段代码:

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;
}

可以编译并运行良好,但是由于没有提出好的搜索词组合,因此我没有找到对此更改的很好的解释。

因此,我的问题不是“如何检查ofstream的有效性”。已经有一些或多或少令人满意的答案(“或多或少”,因为问题似乎有点复杂)。
在这里这里这里

我的问题要解释一下GCC 4和GCC 6之间在编译(export < 0)上述代码中所做的更改

谢谢您的指点。

眼睛的树

在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是一个关键字,不应用作名称。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章