当前位置:  开发笔记 > 编程语言 > 正文

检查流引用是否为NULL不再编译

如何解决《检查流引用是否为NULL不再编译》经验,为你挑选了3个好方法。

我正在用我最新的gcc g ++编译器编译一个过时的项目,(版本> 6)

有一个CodeWriterostream引用变量的类.

class CodeWriter
{
  //private:
protected:
  ostream &m_stream;
public:
  CodeWriter(ostream &stream):m_stream(stream){}
  ~CodeWriter(){
    if(m_stream != NULL){
      m_stream.flush();
    }
  }
};

这个类非常大,所以我只包含了相关的变量和函数.

正如您所看到的,析构函数似乎是在比较引用NULL.当我用旧的gnu工具链使用它时,这个项目编译得很好.

但现在它抛出一个错误,说没有匹配operator !=比较ostreamlong int.

任何人都可以解释改变背后的理由,以及我如何解决这个问题?

如果需要,我很乐意提供更多信息/包括全班.



1> songyuanyao..:

代码不是将引用本身与之NULL比较,而是将引用对象与之进行比较NULL.引用NULL不可能,并且不可能将引用本身与之比较NULL.

当我用旧的gnu工具链使用它时,这个项目编译了我.

因为自C++ 11以来行为发生了变化.

C++ 11之前,std::ostream可被隐式转换为void*经由操作者无效*() ,它返回一个空指针,如果在流错误发生.所以代码的初衷是检查流是否没有错误.

从C++ 11开始,转换函数被更改为explicit operator bool(),false如果发生错误则返回.注意函数被声明为explicit,这意味着bool不允许隐式转换为,所以代码不会再次使用C++ 11编译,因为std::ostream无法bool隐式转换(然后与NULL(整数文字)进行比较) .

使用兼容C++ 11的编译器,您只需将代码更改为

if (m_stream) {
  m_stream.flush();
}

请注意,对于上下文转换,甚至会考虑显式转换函数.对于上面的代码,m_stream将转换为boolvia explicit operator bool(),然后该值将用于条件if.



2> Kerrek SB..:

可以始终在布尔上下文中评估流,因此只需将其更改为:

if (m_stream) {
  m_stream.flush();
}

C++ 11转换为bool explicit.这相当于if (!m_stream.fail()).在C++ 11之前,这种简短的可检查性是通过提供(隐式!)转换来实现的void*,这就是您的旧代码以前工作的原因.

代码检查这个而不是直接调用的m_stream.flush();原因可能是流可能有异常启用失败而且可能抛出,[update:]但是,正如@Arne指出的那样,flush它本身也可能失败并抛出.如果没有异常,你可以完全跳过布尔检查.[/ update]


我敢打赌,在刷新之前测试流是否有效的原因与在删除之前测试指针是否为空的原因相同:想要在不理解库规范的情况下"安全".

3> Bo Persson..:

流类operator void*()在pre-C++ 11中有一个基类.当然,void*价值可以与之比较NULL.

在当前的C++中,这是explicit operator bool()if语句的上下文中工作的,而不是在一般表达式中.

使用a void*是为了避免bool在我们没有explicit运营商时发生的一些不必要的转换.

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有