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

basic_
ostream& operator<<(basic_ostream&(*)(basic_ostream &))
函數(shù)來(lái)接受這個(gè)endl。
如果想寫(xiě)個(gè)類(lèi),比如一個(gè)log類(lèi),希望可以像標(biāo)準(zhǔn)流一樣的輸出,需要做什么呢?
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
};
有了這個(gè)定義后,Log類(lèi)就可以像標(biāo)準(zhǔn)輸出流一樣用了,比如:
1
Log log;
2
log<<123<<"ABC"<<132.32<<endl;
什么,編譯出錯(cuò),而且不止一個(gè)。上面說(shuō)過(guò),是endl引起的問(wèn)題。
std::endl的定義本身就是個(gè)模板函數(shù),用一個(gè)模板函數(shù)(編譯時(shí)連參數(shù)都確定不下來(lái))去推導(dǎo)模板參數(shù),是極不現(xiàn)實(shí)的。
因?yàn)?endl有兩個(gè)模板參數(shù),_Elem 和 _Traits,其實(shí)_Traints 本身就是個(gè)以_Elem為參數(shù)的類(lèi)模板,標(biāo)準(zhǔn)庫(kù)里面有兩個(gè)endl版本,
一個(gè)是 _Elem = char, 另一個(gè)是 _Elem = wchar.
所以編譯器不能推導(dǎo)出Log類(lèi)的operator<<的模板參數(shù)T,于是就錯(cuò)誤了。
解決方案,之前也說(shuō)過(guò),需要一個(gè)接受函數(shù)指針的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
}
有這個(gè)定義,就可以順利使用 <<std::endl 了。
當(dāng)然可以為wchar定義一個(gè)operator<<來(lái)使用寬字符,這都是函數(shù)重載惹的禍呀。因?yàn)閏har和wchar算是endl函數(shù)兩個(gè)重載版本。
問(wèn)題解決了,說(shuō)一下,同樣的函數(shù)還有:
ends,輸入一個(gè)字符串結(jié)束符。
flush,刷新流。
當(dāng)然這倆個(gè)不常用。
posted on 2009-04-18 19:42
尹東斐 閱讀(4399)
評(píng)論(4) 編輯 收藏 引用