【问题标题】:Overloading the standard operator<< for std::complex为 std::complex 重载标准运算符<<
【发布时间】:2014-11-04 22:01:32
【问题描述】:

有没有办法替换默认的

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

带有我自己版本的标准库?我不能只使用上面的签名重载它,因为编译器抱怨(这是正确的)关于模棱两可的调用。我需要这样的重载,因为我想以不同的格式显示std::complex 数字,例如a + b*i,而不是默认的(a,b)

我可以简单地做到这一点

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

但这不是std 中使用的通用版本,不会被其他库调用,例如 Eigen。

【问题讨论】:

    标签: c++ c++11 operator-overloading eigen


    【解决方案1】:

    你能做的——至少因为你已经愿意采取官方禁止的方法来向namespace std添加一些与用户定义的类无关的东西——就是为你的类型明确地专门化它需要。

    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;
    }
    

    然后编译器将选择完美匹配而不是模板版本。为您需要的每种类型重载它。

    但是请注意,遵循 C++ 标准,这会产生未定义的行为,因为您可能不会向 namespace std 添加任何内容来替换现有的实现。

    不过,它似乎至少在使用 g++ 编译器的 ideone.com 上有效,并且可能对于其他现代编译器也是如此[这个猜测基于 this thread here]

    【讨论】:

    • 谢谢,它可以编译和工作,但是,如果我使用例如std::cout &lt;&lt; eigen_matrix,其中eigen_matrix 是来自 Eigen3 库的矩阵,它仍然以旧格式显示它们。特征矩阵重载operator&lt;&lt; 以显示复杂的矩阵,但是在重载中他们仍然调用std::ostream&amp; operator&lt;&lt;。这是我遇到的主要问题,因为我有兴趣在不编写另一个自定义显示函数的情况下显示这些矩阵。 PS:矩阵超过complex&lt;double&gt;,所以原则上应该使用重载显示复数,但事实并非如此。
    • 它实际上可能与 ADL 有关,将进行调查,因为矩阵的 operator&lt;&lt; 是在 Eigen 命名空间中声明的,并且将首先找到 std::complexstd 重载,位于至少这是我的猜测......
    • 是的,这就是发生的事情,如果我用namespace Eigen{ ... } 包围上面的定义,它就像一个魅力!谢谢!
    • 您也可以不将运算符放在命名空间 std 中,它也可以正常工作,从而避免未定义的行为。例如。 ideone.com/AQaB2X
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 2021-01-06
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多