標籤:

C++在類模板中如何定義友元函數為同類型的模板函數?

在Problem Solving with C++中有以下的程序代碼

genericlist.h:

template&
class GenericList
{
public:
friend ostream operator &<&<(ostream outs, const GenericList& the_list);
}

genericlist.cpp:

template&
ostream operator &<&<(ostream outs, const GenericList& the_list)
{
for (int i = 0; i &< the_list.current_length; i++) outs &<&< the_list.item[i] &<&< endl; return outs; }

在GCC 6.2.1中給了如下的報錯:

In file included from main.cpp:3:0:

genericlist.h:39:74: warning: friend declaration 『std::ostream listsavitch::operator&<&<(std::ostream, const listsavitch::GenericList&)』 declares a non-template function [-Wnon-template-friend]

const GenericList& the_list);

^

genercilist.h:39:74: note: (if this is not what you intended, make sure the function template has already been declared and add &<&> after the function name here)

/tmp/ccjBiwS3.o: In function `main":

main.cpp:(.text+0x59): undefined reference to `listsavitch::operator&<&<(std::ostream, listsavitch::GenericList& const)"

main.cpp:(.text+0xbe): undefined reference to `listsavitch::operator&<&<(std::ostream, listsavitch::GenericList& const)"

collect2: error: ld returned 1 exit status

在網上搜索時發現的解決方案為修改函數聲明,添加一個template class成:

genericlist.h

template&
class GenericList
{
public:
&
friend ostream operator &<&<(ostream outs, const GenericList& the_list);
}

genericlist.cpp

template&
ostream operator &<&<(ostream outs, const GenericList& the_list)
{
for (int i = 0; i &< the_list.current_length; i++) outs &<&< the_list.item[i] &<&< endl; return outs; }

但是這樣修改了template class後會不會出現什麼問題,怎樣聲明友元函數為類模板的模板函數?

完整程序在

https://gist.github.com/WallyYang/a874e2c3339616c0ecc5a5796be10d9e


friend函數是不能偏特化的,你只能寫:

template&
class GenericList
{
public:
tempalte&
friend ostream operator &<&<(ostream outs, const GenericList& the_list);
}

然後允許任何operator&<&<的實例都能看到任何GenericList的內容。


都友元了,那就是獨立於這個類之外的東西咯,不管你聲明在哪裡。你的修改是正確的,「友元函數為類模板的模板函數」這個概念是錯誤的。


Templates, C++ FAQ

最好的辦法就是寫個內聯的友元

friend ostream operator &<&<(ostream outs, const GenericList& the_list)
{
//...
}

反正它們也分不開, include 個 cpp 文件看著多難受啊

非要分開寫的話,參考

友元函數利用模板重載函數定義?


推薦閱讀:

一段程序在gcc 5.4下編譯後,執行發生段錯誤,在gcc 4.4.7下編譯後,執行正常,什麼原因?
為什麼 C 語言的輸入輸出函數比 C++ 的輸入輸出流要快?
有沒有比較好的自學IT的網站?適用於不管是初學者還是其他段位的程序猿的網站?
如何評價2016年藍橋杯決賽?

TAG:C | CC | GCC |