[英]Change the complex number output format
C ++标准库中有complex<>
模板,它有一个重载的<<运算符,因此它以(real_part,im_part)格式输出复数。 我需要更改该运算符对复数的行为,以便将输出格式更改为完全不同的输出格式。 具体来说,我需要输出格式为real_part\\tim_part
。 我怎么做?
没有直接的方法来替换operator <<
,但你确实有一些选择。 首先,您可以编写自己的函数来打印复数:
template <typename T> void PrintComplex(const complex<T>& c) {
/* ... */
}
如果你仍想使用漂亮的流语法,那么你可以做的一个技巧是创建一个包装complex
的包装类,然后定义自己的operator <<
以不同的方式打印出来。 例如:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
complex<T> c;
};
一旦你有这个,你可以写一些类似的东西
cout << ComplexPrinter<double>(myComplex) << endl;
您可以通过编写类似这样的函数来为此包装对象,从而使其更加清晰:
template <typename T>
ComplexPrinter<T> wrap(const complex<T>& c) {
return ComplexPrinter<T>(c);
}
然后这让你写
cout << wrap(myComplex) << endl;
哪个不完美,但非常好。
关于上面的包装器需要注意的一点是,它有一个隐式转换构造函数,可以将complex<T>
转换为ComplexPrinter<T>
。 这意味着如果你有一个vector< complex<T> >
,你可以通过调用使用你的自定义代码打印出来
vector< complex<double> > v = /* ... */
copy (v.begin(), v.end(), ostream_iterator< ComplexPrinter<double> >(cout, " "));
在输出时,隐式转换构造函数会将complex<double>
转换为包装器,并且您的自定义代码将为您执行打印。
如果你想要非常冒险并且谨慎对待风,你甚至可以编写类,以便它只存储对原始complex
的引用,如下所示:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
const complex<T>& c;
};
这完全消除了任何复制,只是使包装器成为真正complex
的薄单板。 (没有双关语)。 如果你这样做,你必须非常小心,不要在原始对象超出范围的范围边界传递这些对象,但如果它是你想要的,它可能会很好。
希望这可以帮助!
template<class T>
struct my_complex_format_type {
std::complex<T> const &x;
my_complex_format_type(std::complex<T> const &x) : x (x) {}
friend std::ostream& operator<<(std::ostream &out,
my_complex_format_type const &value)
{
out << "format value.x however you like";
return out;
}
};
template<class T>
my_complex_format_type<T> my_complex_format(std::complex<T> const &x) {
return x;
}
void example() {
std::cout << my_complex_format(some_complex);
}
对于complex<T>
任何特定实例化,使用强类型定义(boost具有版本)并在<<调用期间强制转换为该类型。 覆盖该类型的<<。
如果你需要覆盖<<对于complex<T>
任何变化,那么生活将更加艰难。
我在这里对同一个问题的回答是: c ++在虚构部分显示带有i的复数会产生你想要的行为,但会牺牲一些未来不兼容的风险,因为它会在std::
namespace中插入一个模板特化。
没有非常整洁的方法可以做到这一点。 我的建议是放弃iostream并写一些更像C的东西。 写入速度可能更快,读取速度更快,执行速度更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.