0

我打算每當調用m_logger<<"hello"<<"world"時調用一個函數。 m_logger是類型的流。如何重載<<運算符?

所以我決定超載< <具有以下簽名

friend ofstream& operator<<(ofstream &stream,char *str); 

然而,VC編譯器提供了以下錯誤:

error C2666: 'operator <<' : 6 overloads have similar conversions

是否有任何其它的方式來實現這一目標,我的目標是爲了轉移所有將流操作對象轉換爲不同的函數?

創建我自己的calss對象爲我工作,但是我怎樣才能使它像普通的ofstream對象那樣將所有系統定義的類型轉換爲字符串或char *。我知道一種方法是爲每種類型的操作員超載,但是有更清潔的方法

+0

@Kazoom:我編輯了我的答案,以顯示將任何內容傳遞給內部'ofstream'(它使用函數模板)的通用方法。 – Zifre 2009-07-16 13:25:45

回答

2

問題是ofstream已經超載這種方式。如果您mlogger新型持有ofstream的,那麼你可以這樣做:

class mlogger_t { 
public: 
    ofstream stream; 
    ... 
} 

mlogger_t& operator<<(mlogger_t& stream, const string& str) { 
    stream.stream << str; 
    ... 
} 

//EDIT: here is how to make this work for other types too using templates: 
template<typename T> mlogger_t& operator<<(mlogger_t& stream, T val) { 
    stream.stream << val; 
} 

... 

mlogger_t mlogger; 

mlogger << "foo"; 

而且,你一定要使用const string&(正如我在這個例子中所做的那樣),而不是C風格的字符串。如果你真的需要它是C風格,至少使用const char *

+0

這對我有效,但還有一個問題。我需要mlogger像流媒體一樣工作。如果我嘗試寫入除char *以外的整數或類型,則此方法失敗。例如:mlogger << 3;我是否必須重載每個已知類型?爲了這個工作? – Kazoom 2009-07-15 20:08:00

+0

您可以在這種情況下使用模板。 – Zifre 2009-07-16 00:09:06

2

您可以更改m_logger對象的類型。

5

「過載」不是「覆蓋」。您可以爲不同類型的參數重載函數或運算符;你不能用你自己的實現覆蓋現有的函數或操作符(除了重寫虛擬函數,這顯然是非常不同的)。唯一的例外是operator newoperator delete,其中可以覆蓋內置的。

1

你應該做的是做一個班級,然後定義operator<<。運算符重載必須至少包含一個用戶定義的類型。同樣,你不能寫一個新的operator+(int, int)

2

取決於你爲什麼要重載operator < <,正確的解決方法是,

  • 使用另一種類型比的ostream作爲目標流的後裔;在這種情況下,您必須自己編寫所有運營商< <,但如果您希望默認轉發,則可以從模板獲得幫助。

像這樣:

template <typename T> 
myStream& operator<<(myStream& s, T const& v) 
{ 
    s.getStream() << v; 
} 

,你會看到,操縱不匹配模板,所以你也需要類似:

myStream& operator<<(myStream& fl, std::ostream& (*fn)(std::ostream&)) 
{ 
    s.getStream() << fn; 
} 
  • 寫你自己的streambuf委託I/O到一個std :: filebuf(這有點太複雜了,不能在這裏給出一個例子,搜索網頁 - 過濾streambuf是一個很好的關鍵字。如果我沒有記錯,boost已經可能有用的輔助庫。請注意,在這種情況下,您最終可能會使用另一種類型的fstream,但會從ostream中下載。