教cout优雅地处理空指针

时间:2015-11-17 16:55:02

标签: c++ cout null-pointer

在我的程序中,我处理的是c样式字符串(类型为char *),它们是somtimes NULL。我想教cout优雅地处理那些(即打印"(null)"而不是segfaulting)。

我的第一次尝试:

ostream& operator<< (ostream &out, const char *p_str) {
    if (p_str == nullptr)
        out << "(null)";
    else
        out << p_str;
    return out;
}

不起作用,因为它会导致无限递归(在if和else子句中)。 两个问题:

  1. 我可以通过从我重新定义的版本调用原始operator<<来打破无限递归。我该怎么做呢? (这里缺乏C ++技能......)
  2. 是否有更好的(更惯用的)方式来实现我的目标?

2 个答案:

答案 0 :(得分:3)

快速解决方案是使用std::basic_ostream<>::write成员函数

if (p_str == nullptr)
    out.write("(null)", 6);
else
    out.write(p_str, std::strlen(p_str)); // need to #include <cstring> for std::strlen
return out;

答案 1 :(得分:1)

字符串的原始输出运算符是namespace std

定义的非成员
namespace std {
  template< class CharT, class Traits >
  basic_ostream<CharT,Traits>& operator<<(basic_ostream<CharT,Traits>&, const CharT*);

  template< class CharT, class Traits >
  basic_ostream<CharT,Traits>& operator<<(basic_ostream<CharT,Traits>&, const char*);

  template< class Traits> 
  basic_ostream<char,Traits>& operator<<(basic_ostream<char,Traits>&, const char*);

  template< class Traits >
  basic_ostream<char,Traits>& operator<<(basic_ostream<char,Traits>&, const signed char*);

  template< class Traits >
  basic_ostream<char,Traits>& operator<<(basic_ostream<char,Traits>&, const unsigned char*);
}

并由ADL找到。但是,您当然可以明确地将它们称为(回想std::ostream仅仅是std::basic_ostream<char,std::char_traits<char>>的类型定义)

inline std::ostream& operator<< (std::ostream &out, const char *p_str)
{  
  return std::operator<< (out, p_str==nullptr? "(null)" : p_str);
}

可以在全局命名空间中重载这些运算符(尽管我不确定标准是否允许这样做),尽管我会在您使用它们的命名空间内执行此操作。