相信能看到這里的人,應該都用過std::endl吧,沒見過?
就是hello world后面那個。到底這個endl是個什么東西呢? 答案是:函數指針。
這是它的聲明:
1
template<class _Elem,
2
class _Traits> inline
3
basic_ostream<_Elem, _Traits>&
4
endl(basic_ostream<_Elem, _Traits>& _Ostr)
當然endl只輸入輸出流,輸入流沒有endl。所以輸出流需要一個類似

basic_
ostream& operator<<(basic_ostream&(*)(basic_ostream &))
函數來接受這個endl。
如果想寫個類,比如一個log類,希望可以像標準流一樣的輸出,需要做什么呢?
1
class Log
2

{
3
public:
4
teamplate <typename T>
5
Log& operator<<(const T& t)
6
{
7
// write t to log file.
8
}
9
};
有了這個定義后,Log類就可以像標準輸出流一樣用了,比如:
1
Log log;
2
log<<123<<"ABC"<<132.32<<endl;
什么,編譯出錯,而且不止一個。上面說過,是endl引起的問題。
std::endl的定義本身就是個模板函數,用一個模板函數(編譯時連參數都確定不下來)去推導模板參數,是極不現實的。
因為:endl有兩個模板參數,_Elem 和 _Traits,其實_Traints 本身就是個以_Elem為參數的類模板,標準庫里面有兩個endl版本,
一個是 _Elem = char, 另一個是 _Elem = wchar.
所以編譯器不能推導出Log類的operator<<的模板參數T,于是就錯誤了。
解決方案,之前也說過,需要一個接受函數指針的operator<<的重載版本。
1
Log& operator<<(basic_ostream<char, char_traits<char>>& (*_Pfn)(basic_ostream<char, char_traits<char>>&))
2
{
3
// write endl to log using _Pfn
4
}
有這個定義,就可以順利使用 <<std::endl 了。
當然可以為wchar定義一個operator<<來使用寬字符,這都是函數重載惹的禍呀。因為char和wchar算是endl函數兩個重載版本。
問題解決了,說一下,同樣的函數還有:
ends,輸入一個字符串結束符。
flush,刷新流。
當然這倆個不常用。
posted on 2009-04-18 19:42
尹東斐 閱讀(4370)
評論(4) 編輯 收藏 引用