In my program I handle c style strings (of type char *) that are somtimes NULL. I would like to teach cout to handle those gracefully (i.e. to print "(null)" instead of segfaulting).
My first attempt:
ostream& operator<< (ostream &out, const char *p_str) {
if (p_str == nullptr)
out << "(null)";
else
out << p_str;
return out;
}
Does not work because it leads to an infinite recursion (in both if and else clause). Two questions:
operator<<
from my redefined version. How do I do this? (lacking C++ skills here...)The original output operators for strings are non-members defined in namespace std
as
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*);
}
and are found by ADL. But you can, of course, call them explicitly as in (recall that std::ostream
is merely a typedef to 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);
}
Overloading these operators in the global namespace is possible (though I'm not sure this is allowed by the standard), though I'd do this inside the namespace from which you're using them.