Overloading the standard operator << for std :: complex

Is there a way to replace the default

template <typename T, typename charT, typename traits> 
std::basic_ostream<charT, traits> &
operator << (std::basic_ostream<charT, traits> &strm, const std::complex<T>& c)

      

which comes with the standard library with my own version? I can't just overload it using the above signature, since the compiler is complaining (and rightly so) about an ambiguous call. I need such an overload as I would like to display numbers std::complex

in a different format, for example a + b*i

, instead of the standard one (a,b)

.

I just can do it

template<typename T>
std::ostream& operator<<(std::ostream& os, const std::complex<T>& c)
{
    os << real(z) << " + " << imag(z) << "i";
    return os;
}

      

however, this is not the generic version used in std

, and will not be called by other libraries such as Eigen.

+3


source share


1 answer


What you can do - at least because you're already prepared to take the officially forbidden approach to add something to a namespace std

non-user-defined class - is explicitly specialize it for the types you require.

template <typename charT, typename traits>
std::basic_ostream<charT, traits>&
operator << (std::basic_ostream<charT, traits> &strm, const std::complex<double>& c)    
{
    strm<<c.real()<<"+"<<c.imag()<<"*i";
    return strm;
}

      

The compiler then picks the perfect match, not the boilerplate version. Overload it for every type you need.



Note that following the C ++ standard this creates undefined behavior, since you cannot add anything to namespace std

that replaces existing implementations.

However, it works at least on ideone.com using the g ++ compiler and it is probably the same for other modern compilers [this assumption is based on this thread here ]

+1


source







All Articles