2011-02-14 51 views
5

C++標準庫中有complex<>模板,並且它有一個重載的運算符,因此它以(real_part,im_part)格式輸出複數。我需要改變該運算符對複數的行爲,以便將輸出格式更改爲完全不同的內容。具體來說,我需要輸出的格式爲real_part\tim_part。我怎麼做?更改複數輸出格式

+1

要什麼?你冷淡的想要截斷這個數字,或者想要每次都打印'pear!',你需要指定。 – GManNickG 2011-02-14 07:05:54

回答

7

有沒有直接的方法來取代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; 
}; 

一旦你有了這個,你甚至可以清潔通過編寫一個函數像這樣的包裝對象爲你喜歡寫東西

​​

你可以這樣:

template <typename T> 
ComplexPrinter<T> wrap(const complex<T>& c) { 
    return ComplexPrinter<T>(c); 
} 

這就讓你寫

cout << wrap(myComplex) << endl; 

這並不完美,但很不錯。

有一點需要注意上面的包裝,它有一個隱含的轉換構造函數,可以讓您將complex<T> s轉換爲ComplexPrinter<T> s。這意味着,如果你有一個vector< complex<T> >,您可以使用自定義代碼調用

vector< complex<double> > v = /* ... */ 
copy (v.begin(), v.end(), ostream_iterator< ComplexPrinter<double> >(cout, " ")); 

輸出時,隱式轉換構造函數將改變你的complex<double> S插入包裝打印出來,和您的自定義代碼將執行爲您打印。

如果你想成爲非常冒險和投謹慎的風,你甚至可以寫的類,以便它只是存儲到原來的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。 (沒有雙關語意)。如果你這樣做的話,你必須非常小心,不要將這些對象在原始對象超出範圍的範圍邊界傳遞,但如果這是你想要的,它可能會發揮出色。

希望這會有所幫助!

+0

謝謝!這正是我需要的! – grzkv 2011-02-14 07:25:08

3
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); 
} 
+0

不是說這不是一個很好的答案,但是這幾乎不是我幾分鐘前發佈的嗎? :-) – templatetypedef 2011-02-14 07:11:56

+0

@templatetypedef:我開始閱讀這個問題,然後在發佈前幾分鐘輸入我的答案,並且只在您之後點擊提交67秒。那是問題嗎? – 2011-02-14 07:16:24

-1

有沒有真正乾淨的方法來做到這一點。我的建議就是拋開iostreams,而不是寫更類似C的東西。寫入速度可能會更快,讀取速度更快,執行速度更快。

1

對於complex<T>的任何特定實例,請在< <調用期間使用強類型定義(boost有一個版本)並強制轉換爲該類型。覆蓋該類型的< <。

如果您需要覆蓋< <對於complex<T>的任何變化,那麼生活將變得更加困難。