我只是偶然发现了这段代码:
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] 删除。
我来说两句